Просмотр исходного кода

Added sanity test for logical parent.

Allows early detection of issue #3328.
Steven Kirk 5 лет назад
Родитель
Сommit
39fd3af9ca

+ 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()
         {