public void ScrollToEntity(int index)
        {
            VirtualizingPanel panel = EditorControlUtility.FindVisualChild <VirtualizingPanel>(EntityTree, "");

            if (panel != null)
            {
                panel.BringIndexIntoViewPublic(index);
            }
        }
Example #2
0
        /// <summary>
        /// Navigates to.
        /// http://stackoverflow.com/questions/183636/selecting-a-node-in-virtualized-treeview-with-wpf
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns><see cref="bool"/></returns>
        public bool NavigateTo(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(false);
            }

            FolderService ds = Factory.Resolve <FolderService>();

            FileData root =
                ds.Tree.FirstOrDefault(
                    x => path.StartsWith(x.FullPath + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase));

            if (root == null)
            {
                return(false);
            }

            string[]        pathParts = FolderNavigationService.GetPathParts(path.Substring(root.FullPath.Length));
            List <FileData> tree      = new List <FileData> {
                root
            };

            FileData current = root;

            for (int i = 0; i < pathParts.Length; i++)
            {
                FileData next = current.Children.FirstOrDefault(
                    x => x.IsDirectory == (i != pathParts.Length - 1) &&
                    string.Equals(x.Name, pathParts[i], StringComparison.OrdinalIgnoreCase));
                tree.Add(next);
                current = next;

                if (next == null)
                {
                    return(false);
                }
            }

            ItemsControl currentParent = this.TreeView;

            foreach (FileData node in tree)
            {
                // first try the easy way
                TreeViewItem newParent = currentParent.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
                if (newParent == null)
                {
                    // if this failed, it's probably because of virtualization, and we will have to do it the hard way.
                    // this code is influenced by TreeViewItem.ExpandRecursive decompiled code, and the MSDN sample at http://code.msdn.microsoft.com/Changing-selection-in-a-6a6242c8/sourcecode?fileId=18862&pathId=753647475
                    // see also the question at http://stackoverflow.com/q/183636/46635
                    currentParent.ApplyTemplate();
                    ItemsPresenter itemsPresenter =
                        (ItemsPresenter)currentParent.Template.FindName("ItemsHost", currentParent);
                    if (itemsPresenter != null)
                    {
                        itemsPresenter.ApplyTemplate();
                    }
                    else
                    {
                        currentParent.UpdateLayout();
                    }

                    VirtualizingPanel virtualizingPanel =
                        FolderNavigationService.GetItemsHost(currentParent) as VirtualizingPanel;

                    if (virtualizingPanel == null)
                    {
                        return(false);
                    }

                    FolderNavigationService.CallEnsureGenerator(virtualizingPanel);
                    int index = currentParent.Items.IndexOf(node);
                    if (index < 0)
                    {
                        throw new InvalidOperationException("Node '" + node + "' cannot be found in container");
                    }
                    virtualizingPanel.BringIndexIntoViewPublic(index);
                    newParent = currentParent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                }

                if (newParent == null)
                {
                    throw new InvalidOperationException(
                              "Tree view item cannot be found or created for node '" + node + "'");
                }

                if (node == tree.Last())
                {
                    newParent.IsSelected = true;
                    newParent.BringIntoView();
                    break;
                }

                newParent.IsExpanded = true;
                currentParent        = newParent;
            }
            return(true);
        }
    private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var newNode = e.NewValue as INode;

        if (newNode == null)
        {
            return;
        }
        var behavior    = (NodeTreeSelectionBehavior)d;
        var tree        = behavior.AssociatedObject;
        var nodeDynasty = new List <INode> {
            newNode
        };
        var parent = newNode.Parent;

        while (parent != null)
        {
            nodeDynasty.Insert(0, parent);
            parent = parent.Parent;
        }
        var currentParent = tree as ItemsControl;

        foreach (var node in nodeDynasty)
        {
            // first try the easy way
            var newParent = currentParent.ItemContainerGenerator.ContainerFromItem(node) as TreeViewItem;
            var index     = 0;
            VirtualizingPanel virtualizingPanel = null;
            if (newParent == null)
            {
                // if this failed, it's probably because of virtualization, and we will have to do it the hard way.
                // this code is influenced by TreeViewItem.ExpandRecursive decompiled code, and the MSDN sample at http://code.msdn.microsoft.com/Changing-selection-in-a-6a6242c8/sourcecode?fileId=18862&pathId=753647475
                // see also the question at http://stackoverflow.com/q/183636/46635
                currentParent.ApplyTemplate();
                var itemsPresenter = (ItemsPresenter)currentParent.Template.FindName("ItemsHost", currentParent);
                if (itemsPresenter != null)
                {
                    itemsPresenter.ApplyTemplate();
                }
                else
                {
                    currentParent.UpdateLayout();
                }
                virtualizingPanel = GetItemsHost(currentParent) as VirtualizingPanel;
                CallEnsureGenerator(virtualizingPanel);
                index = currentParent.Items.IndexOf(node);
                if (index < 0)
                {
                    throw new InvalidOperationException("Node '" + node + "' cannot be fount in container");
                }
                if (virtualizingPanel != null)
                {
                    virtualizingPanel.BringIndexIntoViewPublic(index);
                }
                newParent = currentParent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                if (newParent == null)
                {
                    currentParent.UpdateLayout();
                    virtualizingPanel.BringIndexIntoViewPublic(index);
                    newParent = currentParent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                }
            }
            if (newParent == null)
            {
                throw new InvalidOperationException("Tree view item cannot be found or created for node '" + node + "'");
            }
            if (node == newNode)
            {
                newParent.IsSelected = true;
                newParent.BringIntoView();
                break;
            }
            newParent.IsExpanded = true;
            currentParent        = newParent;
        }
    }