Skip to content

Commit

Permalink
Fix leaks on close #171
Browse files Browse the repository at this point in the history
  • Loading branch information
LyonJack committed Jul 3, 2020
1 parent 381c2e1 commit 6ec1e30
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 36 deletions.
6 changes: 5 additions & 1 deletion source/AvalonDocPanelMemoryLeaks/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ public MainWindow()
InitializeComponent();
}

public HeavyLoad HeavyLoad { get; private set; }

private void Button_Click(object sender, RoutedEventArgs e)
{
UserControl content = new UserControl();
content.DataContext = new HeavyLoad();
HeavyLoad = new HeavyLoad();
content.DataContext = HeavyLoad;
LayoutDocument docDocument = new LayoutDocument();
docDocument.Content = content;
docGrup.Children.Add(docDocument);
Expand All @@ -39,6 +42,7 @@ private void Button_Click(object sender, RoutedEventArgs e)

private void DocClosed(object sender, EventArgs e)
{
HeavyLoad.Load = null;
GC.Collect();
}
}
Expand Down
7 changes: 3 additions & 4 deletions source/Components/AvalonDock.Themes.Aero/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -1023,10 +1025,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Background="Transparent" />
<ContentPresenter
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<ContentPresenter />
<!-- Close button should be moved out to the container style -->
<Button
x:Name="DocumentCloseButton"
Expand Down
7 changes: 3 additions & 4 deletions source/Components/AvalonDock.Themes.Expression/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -895,10 +897,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="2" Background="Transparent" />
<ContentPresenter
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<ContentPresenter />
<!-- Close button should be moved out to the container style -->
<Button
x:Name="DocumentCloseButton"
Expand Down
7 changes: 3 additions & 4 deletions source/Components/AvalonDock.Themes.Metro/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -1045,10 +1047,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Background="Transparent" />
<ContentPresenter
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<ContentPresenter />
<!-- Close button should be moved out to the container style -->
<Button
x:Name="DocumentCloseButton"
Expand Down
7 changes: 3 additions & 4 deletions source/Components/AvalonDock.Themes.VS2010/Theme.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -1091,10 +1093,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Background="Transparent" />
<ContentPresenter
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<ContentPresenter />
<!-- Close button should be moved out to the container style -->
<Button
x:Name="DocumentCloseButton"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -1366,12 +1368,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="2" Background="Transparent" />
<ContentPresenter
Margin="4,0"
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
TextBlock.Foreground="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}" />
<ContentPresenter Margin="4,0" TextBlock.Foreground="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}" />
<!-- Close button should be moved out to the container style -->
<Button
x:Name="DocumentCloseButton"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ internal bool IsWin32MouseOver
var rectWindow = this.GetScreenArea();
if (rectWindow.Contains(new Point(ptMouse.X, ptMouse.Y))) return true;

var manager = Model.Root.Manager;
var anchor = manager.FindVisualChildren<LayoutAnchorControl>().Where(c => c.Model == Model).FirstOrDefault();
var manager = Model?.Root.Manager;
var anchor = manager?.FindVisualChildren<LayoutAnchorControl>().Where(c => c.Model == Model).FirstOrDefault();

return anchor != null && anchor.IsMouseOver;
//location = anchor.PointToScreenDPI(new Point());
Expand Down
28 changes: 25 additions & 3 deletions source/Components/AvalonDock/Controls/LayoutDocumentPaneControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ This program is provided to you under the terms of the Microsoft Public
************************************************************************/

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
Expand Down Expand Up @@ -87,11 +89,31 @@ protected override void OnMouseRightButtonDown(System.Windows.Input.MouseButtonE
_model.SelectedContent.IsActive = true;
}

#endregion Overrides
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (var item in e.OldItems)
{
if (item is LayoutContent layoutContent)
{
layoutContent.TabItem.Model = null;
layoutContent.TabItem.ContextMenu = null;
layoutContent.TabItem.Content = null;
var panel = layoutContent.TabItem.FindVisualAncestor<Panel>();
if (panel != null) panel.Children.Remove(layoutContent.TabItem);
layoutContent.TabItem = null;
}
}
}
}

#endregion Overrides

#region Private Methods
#region Private Methods

private void OnSizeChanged(object sender, SizeChangedEventArgs e)
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
var modelWithAtcualSize = _model as ILayoutPositionableElementWithActualSize;
modelWithAtcualSize.ActualWidth = ActualWidth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace AvalonDock.Controls
/// document from its docking position.
/// </summary>
/// <seealso cref="Control"/>
public class LayoutDocumentTabItem : Control
public class LayoutDocumentTabItem : ContentControl
{
#region fields
private List<Rect> _otherTabsScreenArea = null;
Expand Down Expand Up @@ -69,8 +69,10 @@ public LayoutContent Model
/// <summary>Provides derived classes an opportunity to handle changes to the <see cref="Model"/> property.</summary>
protected virtual void OnModelChanged(DependencyPropertyChangedEventArgs e)
{
DockingManager manager = Model?.Root?.Manager;
SetLayoutItem(manager != null ? manager.GetLayoutItemFromModel(Model) : null);
var layoutItem = (Model?.Root?.Manager)?.GetLayoutItemFromModel(Model);
SetLayoutItem(layoutItem);
if (layoutItem != null)
Model.TabItem = this;
//UpdateLogicalParent();
}

Expand Down
2 changes: 2 additions & 0 deletions source/Components/AvalonDock/DockingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,8 @@ internal void ExecuteCloseCommand(LayoutDocument document)
}
if (!document.CloseDocument()) return;
RemoveViewFromLogicalChild(document);
if (document.Content is UIElement uIElement)
RemoveLogicalChild(uIElement);
DocumentClosed?.Invoke(this, new DocumentClosedEventArgs(document));
}

Expand Down
6 changes: 6 additions & 0 deletions source/Components/AvalonDock/Layout/LayoutContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,11 @@ public bool IsEnabled

#endregion IsEnabled

#region TabItem
public LayoutDocumentTabItem TabItem { get; internal set; }

#endregion TabItem

#endregion Properties

#region Public Methods
Expand Down Expand Up @@ -723,6 +728,7 @@ internal void CloseInternal()

parentAsContainer.RemoveChild(this);
root?.CollectGarbage();
this.Content = null;
OnClosed();
}

Expand Down
8 changes: 3 additions & 5 deletions source/Components/AvalonDock/Themes/generic.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@
</Style>

<Style TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
<Setter Property="ContentTemplate" Value="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="ContentTemplateSelector" Value="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentTabItem}">
Expand All @@ -769,11 +771,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="3" Background="Transparent" />
<ContentPresenter
Content="{Binding Model, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding DocumentHeaderTemplate, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}"
ContentTemplateSelector="{Binding DocumentHeaderTemplateSelector, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type avalonDock:DockingManager}, Mode=FindAncestor}}" />

<ContentPresenter />
<Button
x:Name="DocumentCloseButton"
Grid.Column="2"
Expand Down

0 comments on commit 6ec1e30

Please sign in to comment.