Explorar o código

Fixed children being attached to the visual or logical tree multiple times

Tom Edwards %!s(int64=2) %!d(string=hai) anos
pai
achega
b400a1f72d

+ 1 - 1
src/Avalonia.Base/StyledElement.cs

@@ -891,7 +891,7 @@ namespace Avalonia
 
 
             for (var i = 0; i < logicalChildrenCount; i++)
             for (var i = 0; i < logicalChildrenCount; i++)
             {
             {
-                if (logicalChildren[i] is StyledElement child)
+                if (logicalChildren[i] is StyledElement child && child._logicalRoot != e.Root) // child may already have been attached within an event handler
                 {
                 {
                     child.OnAttachedToLogicalTreeCore(e);
                     child.OnAttachedToLogicalTreeCore(e);
                 }
                 }

+ 1 - 1
src/Avalonia.Base/Visual.cs

@@ -487,7 +487,7 @@ namespace Avalonia
 
 
             for (var i = 0; i < visualChildrenCount; i++)
             for (var i = 0; i < visualChildrenCount; i++)
             {
             {
-                if (visualChildren[i] is { } child)
+                if (visualChildren[i] is { } child && child._visualRoot != e.Root) // child may already have been attached within an event handler
                 {
                 {
                     child.OnAttachedToVisualTreeCore(e);
                     child.OnAttachedToVisualTreeCore(e);
                 }
                 }

+ 3 - 3
tests/Avalonia.Controls.UnitTests/MenuItemTests.cs

@@ -250,13 +250,13 @@ namespace Avalonia.Controls.UnitTests
                 Assert.Equal(0, canExecuteCallCount);
                 Assert.Equal(0, canExecuteCallCount);
 
 
                 flyout.ShowAt(button);
                 flyout.ShowAt(button);
-                Assert.Equal(2, canExecuteCallCount);
+                Assert.Equal(1, canExecuteCallCount);
 
 
                 command.RaiseCanExecuteChanged();
                 command.RaiseCanExecuteChanged();
-                Assert.Equal(3, canExecuteCallCount);
+                Assert.Equal(2, canExecuteCallCount);
 
 
                 target.CommandParameter = true;
                 target.CommandParameter = true;
-                Assert.Equal(4, canExecuteCallCount);
+                Assert.Equal(3, canExecuteCallCount);
             }
             }
         }
         }