diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs index 9ab700fba7..2f5e1ed280 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs @@ -26,6 +26,7 @@ namespace Debugger.AddIn.Visualizers.Graph { Canvas canvas; TextBlock edgeTooltip = new TextBlock(); + static double animationDurationSeconds = 0.5; public GraphDrawer(Canvas canvas) { @@ -50,8 +51,7 @@ namespace Debugger.AddIn.Visualizers.Graph return; } - double seconds = 0.5; - var durationMove = new Duration(TimeSpan.FromSeconds(seconds)); + var durationMove = new Duration(TimeSpan.FromSeconds(animationDurationSeconds)); var durationFade = durationMove; DoubleAnimation fadeOutAnim = new DoubleAnimation(1.0, 0.0, durationFade); @@ -82,7 +82,14 @@ namespace Debugger.AddIn.Visualizers.Graph PointAnimation anim = new PointAnimation(); if (first) { - anim.Completed += new EventHandler((o, e) => { Draw(newGraph); }); + anim.Completed += (o, e) => { + Draw(newGraph); + if (oldGraph != null) { + foreach (var oldNode in oldGraph.Nodes) { + oldNode.ReleaseNodeVisualControl(); + } + } + }; first = false; } anim.From = node.LeftTop; 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 79a87e459c..881a90d09f 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 @@ -59,6 +59,11 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing /// public void SetDataContext(PositionedNode node) { + if (node == null) { + this.DataContext = null; + this.listView.ItemsSource = null; + return; + } this.DataContext = node; this.Root = node.Content; this.items = GetInitialItems(this.Root); @@ -97,25 +102,19 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing void PropertyExpandButton_Click(object sender, RoutedEventArgs e) { var clickedButton = (ToggleButton)e.Source; - ContentPropertyNode clickedNode = null; - try - { - clickedNode = (ContentPropertyNode)(clickedButton).DataContext; - } - catch(InvalidCastException) - { - throw new InvalidOperationException("Clicked property expand button, button shouln't be there - DataContext is not PropertyNodeViewModel."); + if (clickedButton.DataContext == null) return; + ContentPropertyNode clickedNode = clickedButton.DataContext as ContentPropertyNode; + clickedNode = clickedButton.DataContext as ContentPropertyNode; + if (clickedNode == null) { + throw new InvalidOperationException("Clicked property expand button, button shouln't be there - DataContext is not ContentPropertyNode."); } PositionedNodeProperty property = clickedNode.Property; - clickedButton.Content = property.IsPropertyExpanded ? "-" : "+"; + clickedButton.Content = property.IsPropertyExpanded ? "-" : "+"; // could be done with a converter - if (property.IsPropertyExpanded) - { + if (property.IsPropertyExpanded) { OnPropertyExpanded(property); - } - else - { + } else { OnPropertyCollapsed(property); } } @@ -123,7 +122,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing void NestedExpandButton_Click(object sender, RoutedEventArgs e) { var clickedButton = (ToggleButton)e.Source; - var clickedNode = (ContentNode)(clickedButton).DataContext; + var clickedNode = clickedButton.DataContext as ContentNode; + if (clickedNode == null) return; int clickedIndex = this.items.IndexOf(clickedNode); clickedButton.Content = clickedNode.IsExpanded ? "-" : "+"; // could be done by a converter @@ -199,8 +199,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing void SetEdgeStrokeThickness(ListViewItem listViewItem, int thickness) { - var clickedNode = (ContentNode)listViewItem.DataContext; - var propNode = clickedNode as ContentPropertyNode; + var propNode = listViewItem.DataContext as ContentPropertyNode; + if (propNode == null) { + return; + } if (propNode != null && propNode.Property != null && propNode.Property.Edge != null && propNode.Property.Edge.Spline != null) { propNode.Property.Edge.Spline.StrokeThickness = thickness; } 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 8917cfaba6..19ae1e5d23 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNode.cs @@ -56,6 +56,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout /// public PositionedGraphNodeControl NodeVisualControl { get; private set; } + public void ReleaseNodeVisualControl() + { + this.NodeVisualControl.SetDataContext(null); + this.NodeVisualControl = null; + } + void InitContentFromObjectNode(Expanded expanded) { this.Content = new ContentNode(this, null); diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs index c419c029bb..6f1cefb945 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs @@ -62,8 +62,6 @@ namespace Debugger.AddIn.Visualizers.Graph public void Refresh() { - Log.Info("Object graph - refresh"); - GC.Collect(); // Almost all of the blocking is done ContentPropertyNode.Evaluate, // which is being called by WPF for all the properties. // It would be better if we were filling the node texts ourselves in a loop,