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