diff --git a/src/Avalonia.Layout/Layoutable.cs b/src/Avalonia.Layout/Layoutable.cs
index 91c230b877..7624928e4b 100644
--- a/src/Avalonia.Layout/Layoutable.cs
+++ b/src/Avalonia.Layout/Layoutable.cs
@@ -603,6 +603,17 @@ namespace Avalonia.Layout
return finalSize;
}
+ ///
+ protected override sealed void OnVisualParentChanged(IVisual oldParent, IVisual newParent)
+ {
+ foreach (ILayoutable i in this.GetSelfAndVisualDescendents())
+ {
+ i.InvalidateMeasure();
+ }
+
+ base.OnVisualParentChanged(oldParent, newParent);
+ }
+
///
/// Calls on the control on which a property changed.
///
diff --git a/src/Avalonia.SceneGraph/Visual.cs b/src/Avalonia.SceneGraph/Visual.cs
index fb4cb21a7c..54786ac85a 100644
--- a/src/Avalonia.SceneGraph/Visual.cs
+++ b/src/Avalonia.SceneGraph/Visual.cs
@@ -384,6 +384,16 @@ namespace Avalonia
DetachedFromVisualTree?.Invoke(this, e);
}
+ ///
+ /// Called when the control's visual parent changes.
+ ///
+ /// The old visual parent.
+ /// The new visual parent.
+ protected virtual void OnVisualParentChanged(IVisual oldParent, IVisual newParent)
+ {
+ RaisePropertyChanged(VisualParentProperty, oldParent, newParent, BindingPriority.LocalValue);
+ }
+
///
/// Called when a property changes that should invalidate the visual.
///
@@ -499,7 +509,7 @@ namespace Avalonia
OnAttachedToVisualTreeCore(e);
}
- RaisePropertyChanged(VisualParentProperty, old, value, BindingPriority.LocalValue);
+ OnVisualParentChanged(old, value);
}
///
diff --git a/tests/Avalonia.Layout.UnitTests/MeasureTests.cs b/tests/Avalonia.Layout.UnitTests/MeasureTests.cs
index 71a38c14db..b5a3539da9 100644
--- a/tests/Avalonia.Layout.UnitTests/MeasureTests.cs
+++ b/tests/Avalonia.Layout.UnitTests/MeasureTests.cs
@@ -44,6 +44,23 @@ namespace Avalonia.Layout.UnitTests
Assert.Equal(new Size(0, 0), panel.DesiredSize);
}
+ [Fact]
+ public void Removing_From_Parent_Should_Invalidate_Measure_Of_Control_And_Descendents()
+ {
+ var panel = new StackPanel();
+ var child2 = new Border();
+ var child1 = new Border { Child = child2 };
+ panel.Children.Add(child1);
+
+ panel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
+ Assert.True(child1.IsMeasureValid);
+ Assert.True(child2.IsMeasureValid);
+
+ panel.Children.Remove(child1);
+ Assert.False(child1.IsMeasureValid);
+ Assert.False(child2.IsMeasureValid);
+ }
+
[Fact]
public void Negative_Margin_Larger_Than_Constraint_Should_Request_Width_0()
{