瀏覽代碼

Added sanity test for logical parent.

Allows early detection of issue #3328.
Steven Kirk 6 年之前
父節點
當前提交
39fd3af9ca
共有 2 個文件被更改,包括 29 次插入0 次删除
  1. 6 0
      src/Avalonia.Styling/StyledElement.cs
  2. 23 0
      tests/Avalonia.Styling.UnitTests/StyledElementTests.cs

+ 6 - 0
src/Avalonia.Styling/StyledElement.cs

@@ -704,6 +704,12 @@ namespace Avalonia
 
         private void OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e)
         {
+            if (this.GetLogicalParent() == null && !(this is IStyleRoot))
+            {
+                throw new InvalidOperationException(
+                    $"AttachedToLogicalTreeCore called for '{GetType().Name}' but control has no logical parent.");
+            }
+
             // This method can be called when a control is already attached to the logical tree
             // in the following scenario:
             // - ListBox gets assigned Items containing ListBoxItem

+ 23 - 0
tests/Avalonia.Styling.UnitTests/StyledElementTests.cs

@@ -76,6 +76,29 @@ namespace Avalonia.Styling.UnitTests
             Assert.Null(target.InheritanceParent);
         }
 
+        [Fact]
+        public void Adding_Element_With_Null_Parent_To_Logical_Tree_Should_Throw()
+        {
+            var target = new Border();
+            var visualParent = new Panel();
+            var logicalParent = new Panel();
+            var root = new TestRoot();
+
+            // Set the logical parent...
+            ((ISetLogicalParent)target).SetParent(logicalParent);
+
+            // ...so that when it's added to `visualParent`, the parent won't be set again.
+            visualParent.Children.Add(target);
+
+            // Clear the logical parent. It's now a logical child of `visualParent` but doesn't have
+            // a logical parent itself.
+            ((ISetLogicalParent)target).SetParent(null);
+
+            // In this case, attaching the control to a logical tree should throw.
+            logicalParent.Children.Add(visualParent);
+            Assert.Throws<InvalidOperationException>(() => root.Child = logicalParent);
+        }
+
         [Fact]
         public void AttachedToLogicalParent_Should_Be_Called_When_Added_To_Tree()
         {