diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingObservableCollection.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingObservableCollection.cs index fcef73bfa9..93f59f3efe 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingObservableCollection.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Common/VirtualizingObservableCollection.cs @@ -5,31 +5,33 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Collections.Specialized; namespace Debugger.AddIn.Visualizers.Common { /// - /// Wrapper of ObservableCollection<IEvaluate> - /// with lazy indexer, suitable for Controls that use indexer to query for data as needed (eg. ListView). + /// Proxy wrapping ObservableCollection<IEvaluate> + /// with lazy indexer, suitable for Controls that use indexer to query data as needed (eg. ListView). /// public class VirtualizingObservableCollection : ObservableCollection, IList, IList { - ObservableCollection lazifiedCollection; + ObservableCollection collection; - public VirtualizingObservableCollection(ObservableCollection lazifiedCollection) + public VirtualizingObservableCollection(ObservableCollection collection) { - this.lazifiedCollection = lazifiedCollection; - this.lazifiedCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(lazifiedCollection_CollectionChanged); + this.collection = collection; + this.collection.CollectionChanged += UnderlyingCollection_Changed; } - void lazifiedCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + void UnderlyingCollection_Changed(object sender, NotifyCollectionChangedEventArgs e) { + // Notify when someone changes the underlying collection, so that UI always stays in sync OnCollectionChanged(e); } public new int Count { - get { return this.lazifiedCollection.Count; } + get { return this.collection.Count; } } /// @@ -39,16 +41,12 @@ namespace Debugger.AddIn.Visualizers.Common { get { - var underlyingItem = this.lazifiedCollection[index]; + var underlyingItem = this.collection[index]; IEvaluate itemLazy = underlyingItem as IEvaluate; - if (itemLazy != null) - { - if (!itemLazy.IsEvaluated) - { - itemLazy.Evaluate(); - } + if (itemLazy != null && (!itemLazy.IsEvaluated)) { + itemLazy.Evaluate(); } - // return item, evaluated if it was IEvaluate + // return evaluated items return underlyingItem; } set diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml index 639d04145f..3295f4896c 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml @@ -18,7 +18,7 @@ Hello --> - + @@ -85,7 +85,7 @@ - + @@ -95,7 +95,7 @@ - + diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs index b6633bd5cb..f9e9596b47 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs @@ -46,7 +46,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing // shown in the ListView - private ObservableCollection view = new ObservableCollection(); + private ObservableCollection items = new ObservableCollection(); private ContentNode root; /// @@ -55,19 +55,11 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing public ContentNode Root { get { return this.root; } - set - { + set { this.root = value; - this.view = getInitialView(this.root); + this.items = GetInitialItems(this.root); // data virtualization, ContentPropertyNode implements IEvaluate - this.listView.ItemsSource = new VirtualizingObservableCollection(this.view); - - /*int maxLen = this.view.MaxOrDefault(contentNode => { return contentNode.Name.Length; }, 0); - int spaces = Math.Max((int)(maxLen * 1.8 - 3), 0); - string addedSpaces = StringHelper.Repeat(' ', spaces); - GridView gv = listView.View as GridView; - // hack - autosize Name column - gv.Columns[1].Header = "Name" + addedSpaces;*/ + this.listView.ItemsSource = new VirtualizingObservableCollection(this.items); //AutoSizeColumns(); @@ -108,14 +100,28 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing } } - public PositionedGraphNodeControl() + public void CalculateWidthHeight() { - InitializeComponent(); - Init(); + int maxLen = this.items.MaxOrDefault(contentNode => contentNode.Name.Length, 0); + int spaces = Math.Max((int)(maxLen * 1.8 - 3), 0); + GridView gv = listView.View as GridView; + gv.Columns[1].Width = 50 + spaces * 2.5; + gv.Columns[2].Width = 80; + listView.Width = gv.Columns[0].Width + gv.Columns[1].Width + gv.Columns[2].Width + 10; + + int maxItems = 10; + listView.Height = Math.Min(this.items.Count, maxItems) * 20; + if (this.items.Count > maxItems) { + listView.Width += 30; // for scrollbar + } + + this.Width = listView.Width + 2; + this.Height = listView.Height + 2; } - public void Init() + public PositionedGraphNodeControl() { + InitializeComponent(); PropertyExpanded = null; PropertyCollapsed = null; ContentNodeExpanded = null; @@ -165,7 +171,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing { var clickedButton = (ToggleButton)e.Source; var clickedNode = (ContentNode)(clickedButton).DataContext; - int clickedIndex = this.view.IndexOf(clickedNode); + int clickedIndex = this.items.IndexOf(clickedNode); //clickedNode.IsExpanded = !clickedNode.IsExpanded; // done by data binding clickedButton.Content = clickedNode.IsExpanded ? "-" : "+"; // could be done by a converter @@ -175,7 +181,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing int i = 1; foreach (var childNode in clickedNode.Children) { - this.view.Insert(clickedIndex + i, childNode); + this.items.Insert(clickedIndex + i, childNode); i++; } // insertChildren(clickedNode, this.view, clickedIndex); // TODO @@ -184,14 +190,16 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing else { // remove whole subtree - int size = subtreeSize(clickedNode) - 1; + int size = SubtreeSize(clickedNode) - 1; for (int i = 0; i < size; i++) { - this.view.RemoveAt(clickedIndex + 1); + this.items.RemoveAt(clickedIndex + 1); } OnContentNodeCollapsed(clickedNode); } + CalculateWidthHeight(); + //AutoSizeColumns(); // set to Auto again to resize columns @@ -208,14 +216,14 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing this.listView.Width = double.NaN;*/ } - private ObservableCollection getInitialView(ContentNode root) + ObservableCollection GetInitialItems(ContentNode root) { return new ObservableCollection(root.FlattenChildrenExpanded()); } - private int subtreeSize(ContentNode node) + int SubtreeSize(ContentNode node) { - return 1 + node.Children.Sum(child => (child.IsExpanded ? subtreeSize(child) : 1)); + return 1 + node.Children.Sum(child => (child.IsExpanded ? SubtreeSize(child) : 1)); } #region event helpers diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs index 879ce511c6..d167dd507a 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs @@ -90,11 +90,11 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout public double Top { get; set; } public double Width { - get { return NodeVisualControl.DesiredSize.Width; } + get { return NodeVisualControl.Width; } } public double Height { - get { return NodeVisualControl.DesiredSize.Height; } + get { return NodeVisualControl.Height; } } public Point LeftTop @@ -142,5 +142,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout box = new SplineRouting.Box(this); return box.Inflated(padding); } + + public void MeasureVisualControl() + { + if ((this.NodeVisualControl != null)) { + this.NodeVisualControl.CalculateWidthHeight(); + } + } } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs index dad8e40f5f..2ee5a62928 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs @@ -52,6 +52,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout foreach (ObjectGraphNode objectNode in objectGraph.ReachableNodes) { var posNode = new PositionedNode(objectNode); posNode.InitContentFromObjectNode(expanded); + posNode.MeasureVisualControl(); positionedGraph.AddNode(posNode); positionedNodeFor[objectNode] = posNode; } @@ -100,7 +101,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout } } } - root.Measure(); root.SubtreeSize = Math.Max(GetLateralSizeWithMargin(root), subtreeSize); }