Browse Source

Reset inheritance parent in ContentPresenter.

Previously a dangling reference to `ContentPresenter`  was left in place in the ex-child control's `InheritanceParent`. When the child is removed from the `ContentPresenter`, reset the value to the control's logical parent.
Steven Kirk 6 years ago
parent
commit
669c6511d6

+ 1 - 0
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@@ -229,6 +229,7 @@ namespace Avalonia.Controls.Presenters
                 if (oldChild != null)
                 {
                     VisualChildren.Remove(oldChild);
+                    ((ISetInheritanceParent)oldChild).SetParent(oldChild.Parent);
                 }
 
                 if (oldChild?.Parent == this)

+ 31 - 0
tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_InTemplate.cs

@@ -281,6 +281,37 @@ namespace Avalonia.Controls.UnitTests.Presenters
             target.Content = 42;
         }
 
+        [Fact]
+        public void Should_Set_InheritanceParent_Even_When_LogicalParent_Is_Already_Set()
+        {
+            var logicalParent = new Canvas();
+            var child = new TextBlock();
+            var (target, host) = CreateTarget();
+
+            ((ISetLogicalParent)child).SetParent(logicalParent);
+            target.Content = child;
+
+            Assert.Same(logicalParent, child.Parent);
+
+            // InheritanceParent is exposed via StylingParent.
+            Assert.Same(target, ((IStyledElement)child).StylingParent);
+        }
+
+        [Fact]
+        public void Should_Reset_InheritanceParent_When_Child_Removed()
+        {
+            var logicalParent = new Canvas();
+            var child = new TextBlock();
+            var (target, _) = CreateTarget();
+
+            ((ISetLogicalParent)child).SetParent(logicalParent);
+            target.Content = child;
+            target.Content = null;
+
+            // InheritanceParent is exposed via StylingParent.
+            Assert.Same(logicalParent, ((IStyledElement)child).StylingParent);
+        }
+
         (ContentPresenter presenter, ContentControl templatedParent) CreateTarget()
         {
             var templatedParent = new ContentControl