private void RestoreExpandedNodes(string searchText, NavigationPane.NavigationMode searchMode) { if ((searchText != _lastSearchText && searchText.Length > 0) || (searchMode == NavigationPane.NavigationMode.SavedSearch && _lastSearchMode != NavigationPane.NavigationMode.SavedSearch)) { // expand all nodes if there's a search and the search has changed. _treeView.ExpandAll(); } if (searchText.Length == 0 && searchMode != NavigationPane.NavigationMode.SavedSearch) { // if there isn't a search persist the user's expanded nodes. var list = AssignList(searchMode); var allNodes = new List<VirtualTreeNode>(_treeView.AllNodes); foreach (VirtualTreeNode.PersistenceInfo info in list) { VirtualTreeNode match; // First, look for the object in the same position if (_treeView.TryExactMatch(info.Path, out match) >= info.Path.Count) { if (!match.IsExpanded) match.Expand(); allNodes.Remove(match); continue; } // Second, find the object in the maximal sub tree where it appeared only once if (_treeView.TryExactMatch(info.PathToMaximalSubTree, out match) >= info.PathToMaximalSubTree.Count) { match = _treeView.FindNodeIn(match, info.Tag); if (match != null) { if (!match.IsExpanded) match.Expand(); allNodes.Remove(match); } } } // collapse everything else foreach (VirtualTreeNode n in allNodes) { if (n.Tag != null && n.Parent != null && n.IsExpanded) n.Collapse(); } // special case for root node if (_rootExpanded) _treeView.Nodes[0].Expand(); } }
/// <summary> /// Updates the <see cref="TreeView"/> with the specified new root node. This is done by merging the specified /// root node with the existing root node to minimize updates to the treeview to reduce flicker. /// </summary> /// <param name="newRootNode">The new root node.</param> /// <param name="searchText">The search text for the currently active search.</param> public void RefreshTreeView(VirtualTreeNode newRootNode, string searchText, NavigationPane.NavigationMode searchMode) { Util.ThrowIfParameterNull(newRootNode, "newRootNode"); Util.ThrowIfParameterNull(searchText, "searchText"); Program.AssertOnEventThread(); _treeView.BeginUpdate(); PersistExpandedNodes(searchText); _treeView.UpdateRootNodes(new[] { newRootNode }); RestoreExpandedNodes(searchText, searchMode); bool searchTextCleared = (searchText.Length == 0 && searchText != _lastSearchText); _lastSearchText = searchText; _lastSearchMode = searchMode; _treeView.EndUpdate(); // ensure that the selected nodes are visible when search text is cleared (CA-102127) if (searchTextCleared) { ExpandSelection(); } }
private List<VirtualTreeNode.PersistenceInfo> AssignList(NavigationPane.NavigationMode mode) { switch (mode) { case NavigationPane.NavigationMode.Objects: return _objectViewExpanded; case NavigationPane.NavigationMode.Tags: return _tagsViewExpanded; case NavigationPane.NavigationMode.Folders: return _foldersViewExpanded; case NavigationPane.NavigationMode.CustomFields: return _fieldsViewExpanded; case NavigationPane.NavigationMode.vApps: return _vappsViewExpanded; default: return _infraViewExpanded; } }
public VirtualTreeNode CreateNewRootNode(Search search, NavigationPane.NavigationMode mode) { IAcceptGroups groupAcceptor; VirtualTreeNode newRootNode; switch (mode) { case NavigationPane.NavigationMode.Objects: newRootNode = viewObjects.RootNode; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); viewObjects.Populate(search, groupAcceptor); break; case NavigationPane.NavigationMode.Tags: newRootNode = viewTags.RootNode; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); viewTags.Populate(search, groupAcceptor); break; case NavigationPane.NavigationMode.Folders: newRootNode = viewFolders.RootNode; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); viewFolders.Populate(search, groupAcceptor); break; case NavigationPane.NavigationMode.CustomFields: newRootNode = viewFields.RootNode; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); viewFields.Populate(search, groupAcceptor); break; case NavigationPane.NavigationMode.vApps: newRootNode = viewVapps.RootNode; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); viewVapps.Populate(search, groupAcceptor); break; case NavigationPane.NavigationMode.SavedSearch: Util.ThrowIfParameterNull(search, "search"); newRootNode = new VirtualTreeNode(search.Name) { Tag = search, ImageIndex = search.DefaultSearch ? (int)Icons.DefaultSearch : (int)Icons.Search }; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); search.PopulateAdapters(groupAcceptor); break; default://includes Infrastructure and Notifications Util.ThrowIfParameterNull(search, "search"); newRootNode = new VirtualTreeNode("XenCenter") { ImageIndex = (int)Icons.Home }; groupAcceptor = CreateGroupAcceptor(_highlightedDragTarget, newRootNode); search.PopulateAdapters(groupAcceptor); break; } return newRootNode; }