protected override DependencyObject GetContainerForItemOverride() { var treeViewItem = new ProperTreeViewItem(this.treeView); treeViewItem.Indent = this.Indent + 12; return(treeViewItem); }
protected override DependencyObject GetContainerForItemOverride() { if (_pendingRoot != null) { _pendingRoot.Loaded -= OnRootLoaded; _pendingRoot = null; } _pendingRoot = new ProperTreeViewItem(new WeakReference(this)); _pendingRoot.Loaded += OnRootLoaded; _maxDepth = 0; _rootItem.Target = null; return(_pendingRoot); }
public bool ApplyReduceDepthFilterIfNeeded(ProperTreeViewItem curNode) { if (this.pendingRoot != null) { this.OnRootLoaded(); } if (this.maxDepth == 0) { return(false); } var rootItem = (TreeItem)this.rootItem.Target; if (rootItem is null) { return(false); } if (this.snoopUI == null) { this.snoopUI = Window.GetWindow(this) as SnoopUI; if (this.snoopUI is null) { return(false); } } var item = (TreeItem)curNode.DataContext; var selectedItem = this.snoopUI.CurrentSelection; if (selectedItem != null && item.Depth < selectedItem.Depth) { item = selectedItem; } if (item.Depth - rootItem.Depth <= this.maxDepth) { return(false); } for (var i = 0; i < this.maxDepth; ++i) { item = item.Parent; } this.snoopUI.ApplyReduceDepthFilter(item); return(true); }
public bool ApplyReduceDepthFilterIfNeeded(ProperTreeViewItem curNode) { if (_pendingRoot != null) { OnRootLoaded(); } if (_maxDepth == 0) { return(false); } var rootItem = (VisualTreeItem)_rootItem.Target; if (rootItem == null) { return(false); } if (_snoopUi == null) { _snoopUi = this.GetAncestor <SnoopUI>(); if (_snoopUi == null) { return(false); } } var item = (VisualTreeItem)curNode.DataContext; var selectedItem = _snoopUi.CurrentSelection; if (selectedItem != null && item.Depth < selectedItem.Depth) { item = selectedItem; } if ((item.Depth - rootItem.Depth) <= _maxDepth) { return(false); } for (var i = 0; i < _maxDepth; ++i) { item = item.Parent; } _snoopUi.ApplyReduceDepthFilter(item); return(true); }
private void OnRootLoaded() { // The following assumptions are made: // 1. The visual structure of each TreeViewItem is the same regardless of its location. // 2. The control template of a TreeViewItem contains ItemsPresenter. ProperTreeViewItem root = _pendingRoot; _pendingRoot = null; root.Loaded -= OnRootLoaded; ItemsPresenter itemsPresenter = null; root.EnumerateTree(null, delegate(Visual visual, object misc) { itemsPresenter = visual as ItemsPresenter; if (itemsPresenter != null && ReferenceEquals(itemsPresenter.TemplatedParent, root)) { return(HitTestResultBehavior.Stop); } itemsPresenter = null; return(HitTestResultBehavior.Continue); }, null); if (itemsPresenter != null) { int levelLayoutDepth = 2; DependencyObject tmp = itemsPresenter; while (!ReferenceEquals(tmp, root)) { ++levelLayoutDepth; tmp = VisualTreeHelper.GetParent(tmp); } int rootLayoutDepth = 0; while (tmp != null) { ++rootLayoutDepth; tmp = VisualTreeHelper.GetParent(tmp); } _maxDepth = (240 - rootLayoutDepth) / levelLayoutDepth; _rootItem = new WeakReference((VisualTreeItem)root.DataContext); } }
// We need this method and what it does because: // If we have a tree with levels greater than 150 then we might get an StackOverflowException during measure/arrange. // To prevent these Exceptions (which immediately crash the program being snooped) we use the item at the current level (minus a few) as the new root node for the tree. // That way we get a "new" tree that is not as deeply nested as before. public bool ApplyReduceDepthFilterIfNeeded(ProperTreeViewItem curNode) { if (this.maxDepth == 0) { return(false); } if (this.snoopUI is null) { this.snoopUI = Window.GetWindow(this) as SnoopUI; if (this.snoopUI is null) { return(false); } } var item = (TreeItem)curNode.DataContext; var selectedItem = this.snoopUI.CurrentSelection; if (selectedItem is not null && item.Depth < selectedItem.Depth) { item = selectedItem; } var rootItem = this.GetRootItem(); if (rootItem is null) { return(false); } // Do we exceed the current max depth? if (item.Depth - rootItem.Depth <= this.maxDepth) { return(false); } if (item.Parent is null) { return(false); } // Try to show 10 items above new root, that way we can keep a bit of context var newRoot = item.Parent; for (var i = 0; i < 10; ++i) { if (newRoot?.Parent is null) { break; } newRoot = newRoot.Parent; } this.snoopUI.ApplyReduceDepthFilter(newRoot !); return(true); }