diff --git a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs index 854e8d85e8..465fdc10de 100644 --- a/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs @@ -109,6 +109,7 @@ namespace Avalonia.Controls.Presenters static ScrollContentPresenter() { ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true); + AffectsMeasure(CanHorizontallyScrollProperty, CanVerticallyScrollProperty); } /// diff --git a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs index 4a858abc07..3958912378 100644 --- a/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs @@ -477,7 +477,55 @@ namespace Avalonia.Controls.UnitTests var result = converter.Convert(args, typeof(ScrollBarVisibility), "0", System.Globalization.CultureInfo.CurrentCulture); Assert.Equal(true, result); } - + + [Fact] + public void ScrollBar_Visibility_Should_Invalidate_Measure_And_Arrange() + { + var panel = new TestPanel() + { + DesiredWidth = 100_000 + }; + var target = new ScrollViewer + { + Content = panel, + Template = new FuncControlTemplate(CreateTemplate), + HorizontalScrollBarVisibility = ScrollBarVisibility.Auto + }; + var root = new TestRoot(target); + root.LayoutManager.ExecuteInitialLayoutPass(); + panel.Reset(); + + target.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled; + root.LayoutManager.ExecuteLayoutPass(); + Assert.Equal(1, panel.MeasureOverrideCalls); + Assert.Equal(1, panel.ArrangeOverrideCalls); + } + + public class TestPanel : Panel + { + public int DesiredWidth { get; set; } + public int MeasureOverrideCalls { get; private set; } + public int ArrangeOverrideCalls { get; private set; } + + protected override Size MeasureOverride(Size availableSize) + { + MeasureOverrideCalls++; + return new Size(DesiredWidth, 1); + } + + protected override Size ArrangeOverride(Size finalSize) + { + ArrangeOverrideCalls++; + return base.ArrangeOverride(finalSize); + } + + public void Reset() + { + MeasureOverrideCalls = 0; + ArrangeOverrideCalls = 0; + } + } + private Point GetRootPoint(Visual control, Point p) { if (control.GetVisualRoot() is Visual root &&