Browse Source

Correctly remove ContentPresenter's content from its parent host

When the content is updated while being detached from the visual tree.
pull/11178/head
Julien Lebosquain 3 years ago
parent
commit
9a06290142
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 9
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  2. 5
      tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

9
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -1,5 +1,5 @@
using System;
using Avalonia.Collections;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
@ -442,7 +442,7 @@ namespace Avalonia.Controls.Presenters
var contentTemplate = ContentTemplate;
var oldChild = Child;
var newChild = CreateChild(content, oldChild, contentTemplate);
var logicalChildren = Host?.LogicalChildren ?? LogicalChildren;
var logicalChildren = GetEffectiveLogicalChildren();
// Remove the old child if we're not recycling it.
if (newChild != oldChild)
@ -488,6 +488,9 @@ namespace Avalonia.Controls.Presenters
}
private IAvaloniaList<ILogical> GetEffectiveLogicalChildren()
=> Host?.LogicalChildren ?? LogicalChildren;
/// <inheritdoc/>
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
@ -692,7 +695,7 @@ namespace Avalonia.Controls.Presenters
else if (Child != null)
{
VisualChildren.Remove(Child);
LogicalChildren.Remove(Child);
GetEffectiveLogicalChildren().Remove(Child);
((ISetInheritanceParent)Child).SetParent(Child.Parent);
Child = null;
_recyclingDataTemplate = null;

5
tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

@ -359,16 +359,21 @@ namespace Avalonia.Controls.UnitTests
target.Presenter.ApplyTemplate();
Assert.Equal(target, target.Presenter.Child.GetLogicalParent());
Assert.Equal(new[] { target.Presenter.Child }, target.LogicalChildren);
root.Child = null;
Assert.Null(target.Template);
target.Content = null;
Assert.Empty(target.LogicalChildren);
root.Child = target;
target.Content = "Bar";
Assert.Equal(target, target.Presenter.Child.GetLogicalParent());
Assert.Equal(new[] { target.Presenter.Child }, target.LogicalChildren);
}
private static FuncControlTemplate GetTemplate()

Loading…
Cancel
Save