Skip to content

Commit 7d1c1c7

Browse files
authored
UniformGridLayout (FlowLayout): Fix issue with scrolling up creating gaps in layout (#3393)
* Add interaction test * Fix bug * CR feedback
1 parent c7e735a commit 7d1c1c7

7 files changed

Lines changed: 120 additions & 1 deletion

File tree

dev/Repeater/FlowLayoutAlgorithm.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@ void FlowLayoutAlgorithm::Generate(
364364
{
365365
// Does not fit, wrap to the previous row
366366
const auto availableSizeMinor = Minor(availableSize);
367-
MinorStart(currentBounds) = std::isfinite(availableSizeMinor) ? availableSizeMinor - Minor(desiredSize) : 0.0f;
367+
// If the last available size is finite, start from end and subtract our desired size.
368+
// Otherwise, look at the last extent and use that for positioning.
369+
MinorStart(currentBounds) = std::isfinite(availableSizeMinor) ? availableSizeMinor - Minor(desiredSize) : MinorSize(LastExtent()) - Minor(desiredSize);
368370
MajorStart(currentBounds) = lineOffset - Major(desiredSize) - static_cast<float>(lineSpacing);
369371

370372
if (lineNeedsReposition)

dev/Repeater/InteractionTests/RepeaterTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,38 @@ public static void ClassInitialize(TestContext testContext)
3636
TestEnvironment.Initialize(testContext);
3737
}
3838

39+
[TestMethod]
40+
public void VerifyUniformGridLayoutDoesNotCreateHoles()
41+
{
42+
using (var setup = new TestSetupHelper("ItemsRepeater Tests"))
43+
{
44+
// Open page
45+
FindElement.ByName("UniformGridLayoutDemo").Click();
46+
47+
// Scroll down
48+
var scrollviewer = FindElement.ByName("RepeaterScrollViewer");
49+
var repeaterHeightButton = FindElement.ByName("GetRepeaterActualHeightButton");
50+
repeaterHeightButton.Click();
51+
// Get actual repeater height
52+
var oldActualRepeaterHeight = double.Parse(FindElement.ByName("RepeaterActualHeightLabel").GetText());
53+
54+
InputHelper.RotateWheel(scrollviewer, -2000);
55+
Wait.ForIdle();
56+
57+
// Scroll back up again, users don't scroll large offsets at once but rather small chunks in succession.
58+
for(int i=0;i<5;i++)
59+
{
60+
InputHelper.RotateWheel(scrollviewer, 50);
61+
Wait.ForIdle();
62+
}
63+
64+
repeaterHeightButton.Click();
65+
Verify.IsTrue(Math.Abs(oldActualRepeaterHeight -
66+
double.Parse(FindElement.ByName("RepeaterActualHeightLabel").GetText())) < 1,
67+
"Repeater heights did not match. This indicates that there are holes in layout as the repeater now needed more/less space.");
68+
}
69+
}
70+
3971
public void TestCleanup()
4072
{
4173
TestCleanupHelper.Cleanup();

dev/Repeater/TestUI/RepeaterTestUIPage.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<TextBlock Text="Other Samples" Style="{ThemeResource HeaderTextBlockStyle}"/>
8686
<Button x:Name="defaultDemo" AutomationProperties.Name="Default Demo" >Default Demo</Button>
8787
<Button x:Name="basicDemo" AutomationProperties.Name="Basic Demo">Basic Demo</Button>
88+
<Button x:Name="uniformGridLayoutDemo" AutomationProperties.Name="UniformGridLayoutDemo">UniformGridLayout testing</Button>
8889
</StackPanel>
8990

9091
</controls:LayoutPanel>

dev/Repeater/TestUI/RepeaterTestUIPage.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public RepeaterTestUIPage()
3434
Frame.NavigateWithoutAnimation(typeof(BasicDemo));
3535
};
3636

37+
uniformGridLayoutDemo.Click += delegate
38+
{
39+
Frame.NavigateWithoutAnimation(typeof(UniformGridLayoutDemo));
40+
};
41+
3742
itemsSourceDemo.Click += delegate
3843
{
3944
Frame.NavigateWithoutAnimation(typeof(ElementsInItemsSourcePage));
@@ -224,6 +229,7 @@ public RepeaterTestUIPage()
224229
Orientation = orientation.IsOn ? Orientation.Horizontal : Orientation.Vertical,
225230
});
226231
};
232+
227233
}
228234

229235
private VirtualizingLayout GetStackLayout()

dev/Repeater/TestUI/Repeater_TestUI.projitems

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@
108108
<SubType>Designer</SubType>
109109
<Generator>MSBuild:Compile</Generator>
110110
</Page>
111+
<Page Include="$(MSBuildThisFileDirectory)Samples\UniformGridLayoutDemo.xaml">
112+
<SubType>Designer</SubType>
113+
<Generator>MSBuild:Compile</Generator>
114+
</Page>
111115
</ItemGroup>
112116
<ItemGroup>
113117
<Compile Include="$(MSBuildThisFileDirectory)RepeaterTestUIPage.xaml.cs">
@@ -199,6 +203,9 @@
199203
<Compile Include="$(MSBuildThisFileDirectory)Samples\LayoutSamples\NestedLayoutSamples\StoreMockData.cs" />
200204
<Compile Include="$(MSBuildThisFileDirectory)Samples\AnimationSamples\DefaultElementAnimator.cs" />
201205
<Compile Include="$(MSBuildThisFileDirectory)Samples\ItemsSourceSamples\ResetableCollection.cs" />
206+
<Compile Include="$(MSBuildThisFileDirectory)Samples\UniformGridLayoutDemo.cs">
207+
<DependentUpon>UniformGridLayoutDemo.xaml</DependentUpon>
208+
</Compile>
202209
</ItemGroup>
203210
<ItemGroup>
204211
<Content Include="$(MSBuildThisFileDirectory)Images\recipe1.png" />
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
using Microsoft.UI.Xaml.Controls;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Collections.ObjectModel;
8+
using System.Linq;
9+
using Windows.UI.Xaml;
10+
using Windows.UI.Xaml.Controls;
11+
using RecyclingElementFactory = Microsoft.UI.Xaml.Controls.RecyclingElementFactory;
12+
using SelectTemplateEventArgs = Microsoft.UI.Xaml.Controls.SelectTemplateEventArgs;
13+
14+
namespace MUXControlsTestApp.Samples
15+
{
16+
public sealed partial class UniformGridLayoutDemo : Page
17+
{
18+
public IEnumerable<int> collection;
19+
20+
public UniformGridLayoutDemo()
21+
{
22+
collection = Enumerable.Range(0, 40);
23+
this.InitializeComponent();
24+
}
25+
26+
public void GetRepeaterActualHeightButtonClick(object sender, RoutedEventArgs e)
27+
{
28+
RepeaterActualHeightLabel.Text = UniformGridRepeater.ActualHeight.ToString();
29+
}
30+
}
31+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
2+
<Page
3+
x:Class="MUXControlsTestApp.Samples.UniformGridLayoutDemo"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:controls="using:Microsoft.UI.Xaml.Controls">
7+
8+
<Page.Resources>
9+
<!-- The Layout specifications used: -->
10+
<controls:UniformGridLayout x:Name="UniformGridLayout"
11+
MinRowSpacing="8" MinColumnSpacing="8"
12+
MaximumRowsOrColumns="4"/>
13+
14+
<DataTemplate x:Key="SimpleElementTemplate" x:DataType="x:String">
15+
<Grid Background="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
16+
Width="100"
17+
Height="100">
18+
<TextBlock Text="{Binding}"
19+
FontSize="20"/>
20+
</Grid>
21+
</DataTemplate>
22+
</Page.Resources>
23+
<StackPanel Orientation="Horizontal">
24+
<ScrollViewer HorizontalScrollBarVisibility="Auto"
25+
HorizontalScrollMode="Auto"
26+
IsVerticalScrollChainingEnabled="False"
27+
AutomationProperties.Name="RepeaterScrollViewer"
28+
MaxHeight="500">
29+
<controls:ItemsRepeater x:Name="UniformGridRepeater"
30+
ItemsSource="{x:Bind collection}"
31+
Layout="{StaticResource UniformGridLayout}"
32+
ItemTemplate="{StaticResource SimpleElementTemplate}"/>
33+
</ScrollViewer>
34+
<StackPanel>
35+
<Button AutomationProperties.Name="GetRepeaterActualHeightButton"
36+
Click="GetRepeaterActualHeightButtonClick">Get actual Repeater height</Button>
37+
<TextBlock x:Name="RepeaterActualHeightLabel" AutomationProperties.Name="RepeaterActualHeightLabel"/>
38+
</StackPanel>
39+
</StackPanel>
40+
</Page>

0 commit comments

Comments
 (0)