From 565dd040ae8f8f35ef1b31ac9ac7ba6506246d99 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 6 Sep 2024 16:49:21 +0300 Subject: [PATCH] fix: Adjust ScrollContentPresenter measure to prevent infinite available size when necessary --- .../Given_ItemsPresenter.cs | 18 ++++++++++++++++++ .../Controls/ItemsControl/ItemsPresenter.cs | 11 +++++++++++ .../ItemsStackPanel/ItemsStackPanel.cs | 6 ++++++ .../Controls/ItemsWrapGrid/ItemsWrapGrid.cs | 6 ++++++ .../ScrollContentPresenter.cs | 6 ++++-- src/Uno.UI/UI/Xaml/UIElement.mux.cs | 3 +++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ItemsPresenter.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ItemsPresenter.cs index b85fc5cb5166..8e31d6ea5f01 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ItemsPresenter.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_ItemsPresenter.cs @@ -1180,5 +1180,23 @@ public async Task When_Footer_Template() Assert.AreEqual(SUT.FindVisualChildByType().Text, "updated footer value"); } + [TestMethod] + [RunsOnUIThread] + public async Task When_Inside_ScrollContentPresenter() + { + var lv = new ListView(); + ScrollViewer.SetHorizontalScrollBarVisibility(lv, ScrollBarVisibility.Visible); + ScrollViewer.SetHorizontalScrollMode(lv, ScrollMode.Enabled); + lv.Items.Add("1"); + + await UITestHelper.Load(lv); + + var sv = (ScrollViewer)((Border)VisualTreeHelper.GetChild(lv, 0)).Child; + var itemsPresenter = (ItemsPresenter)sv.Content; + + var availableSize = LayoutInformation.GetAvailableSize(itemsPresenter); + Assert.AreNotEqual(double.PositiveInfinity, availableSize.Width); + } + public record MyTextModel(string MyText); } diff --git a/src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsPresenter.cs b/src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsPresenter.cs index 5466a2cd1438..5766d4577b22 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsPresenter.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ItemsControl/ItemsPresenter.cs @@ -348,6 +348,17 @@ private void PropagateLayoutValues() #endif } + internal override bool WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation orientation) + { + return WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(orientation, Panel); + } + + private bool WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation orientation, _ViewGroup spPanel) + { + return (spPanel as FrameworkElement)?.WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(orientation) ?? true; + } + + protected override Size ArrangeOverride(Size finalSize) { // Most of this is inspired by StackPanel's ArrangeOverride diff --git a/src/Uno.UI/UI/Xaml/Controls/ItemsStackPanel/ItemsStackPanel.cs b/src/Uno.UI/UI/Xaml/Controls/ItemsStackPanel/ItemsStackPanel.cs index 0386ac09d38b..83666b93c7f1 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ItemsStackPanel/ItemsStackPanel.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ItemsStackPanel/ItemsStackPanel.cs @@ -102,6 +102,12 @@ void IInsertionPanel.GetInsertionIndexes(Point position, out int first, out int } } } + + // In WinUI, this is actually for ModernCollectionBasePanel + internal override bool WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation orientation) + { + return Orientation == orientation; + } } } diff --git a/src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGrid.cs b/src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGrid.cs index beff09f5d12c..ae53c0b29db8 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGrid.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ItemsWrapGrid/ItemsWrapGrid.cs @@ -56,6 +56,12 @@ VirtualizingPanelLayout IVirtualizingPanel.GetLayouter() } return _layout; } + + // In WinUI, this is actually for ModernCollectionBasePanel + internal override bool WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation orientation) + { + return Orientation == orientation; + } } } diff --git a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs index 607d67c9cee8..9d9c81cadaf1 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.cs @@ -189,14 +189,16 @@ protected override Size MeasureOverride(Size availableSize) if (CanVerticallyScroll) { - if (!sizesContentToTemplatedParent) + var childPreventsInfiniteAvailableHeight = !child.WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation.Vertical); + if (!sizesContentToTemplatedParent && !childPreventsInfiniteAvailableHeight) { slotSize.Height = double.PositiveInfinity; } } if (CanHorizontallyScroll) { - if (!sizesContentToTemplatedParent) + var childPreventsInfiniteAvailableWidth = !child.WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation.Horizontal); + if (!sizesContentToTemplatedParent && !childPreventsInfiniteAvailableWidth) { slotSize.Width = double.PositiveInfinity; } diff --git a/src/Uno.UI/UI/Xaml/UIElement.mux.cs b/src/Uno.UI/UI/Xaml/UIElement.mux.cs index 62dff417d672..576fb61ec38c 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.mux.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.mux.cs @@ -1929,5 +1929,8 @@ internal virtual void LeaveImpl(LeaveParams @params) } #endif + + internal virtual bool WantsScrollViewerToObscureAvailableSizeBasedOnScrollBarVisibility(Orientation horizontal) + => true; } }