Skip to content

Commit 70ed20e

Browse files
Fix crash with unbounded sizing for WrapLayout. (#3330)
* Fix crash with unbounded sizing for WrapLayout. Also add some new stuff to the sample for easier manipulation. * PR fixes * Fix issues with Layout samples in Release Mode Needed to use Visual helpers here, as apparently Logical ones work differently here in Release mode??? * Fix typo pointed out by @skendrot Co-authored-by: Michael Hawker MSFT (XAML Llama) <[email protected]>
1 parent 43c28eb commit 70ed20e

File tree

5 files changed

+51
-4
lines changed

5 files changed

+51
-4
lines changed

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/StaggeredLayout/StaggeredLayoutPage.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public StaggeredLayoutPage()
3434

3535
public void OnXamlRendered(FrameworkElement control)
3636
{
37-
var repeater = control.FindChildByName("StaggeredRepeater") as ItemsRepeater;
37+
var repeater = control.FindDescendantByName("StaggeredRepeater") as ItemsRepeater;
3838

3939
if (repeater != null)
4040
{

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/WrapLayout/WrapLayout.bind

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
<Grid Padding="48">
2121
<winui:ItemsRepeaterScrollHost> <!-- Needed for 1803 and below -->
22-
<ScrollViewer>
22+
<ScrollViewer x:Name="WrapScrollParent">
2323
<winui:ItemsRepeater x:Name="WrapRepeater"
2424
Background="{ThemeResource Brush-Grey-04}"
2525
ItemTemplate="{StaticResource WrapTemplate}">

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/WrapLayout/WrapLayoutPage.xaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@
66
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
88
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
9+
xmlns:winui="using:Microsoft.UI.Xaml.Controls"
910
mc:Ignorable="d"
1011
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
1112

1213
<Page.Resources>
1314
<controls:WrapLayout x:Key="WrapLayoutPlaceholder"/>
1415
</Page.Resources>
16+
17+
<winui:ItemsRepeaterScrollHost>
18+
<ScrollViewer x:Name="WrapScrollParent">
19+
<winui:ItemsRepeater x:Name="WrapRepeater"/>
20+
</ScrollViewer>
21+
</winui:ItemsRepeaterScrollHost>
1522
</Page>

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/WrapLayout/WrapLayoutPage.xaml.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.Collections.ObjectModel;
7+
using Microsoft.Toolkit.Uwp.UI.Controls;
78
using Microsoft.Toolkit.Uwp.UI.Extensions;
89
using Microsoft.UI.Xaml.Controls;
910
using Windows.UI;
@@ -19,11 +20,15 @@ public sealed partial class WrapLayoutPage : Page, IXamlRenderListener
1920
{
2021
private ObservableCollection<Item> _items = new ObservableCollection<Item>();
2122
private Random _random;
23+
private ScrollViewer _wrapScrollParent;
24+
private WrapLayout _wrapLayout;
2225

2326
public WrapLayoutPage()
2427
{
2528
this.InitializeComponent();
2629

30+
SampleController.Current.RegisterNewCommand("Switch Orientation", SwitchButton_Click);
31+
2732
_random = new Random(DateTime.Now.Millisecond);
2833
for (int i = 0; i < _random.Next(1000, 5000); i++)
2934
{
@@ -34,12 +39,16 @@ public WrapLayoutPage()
3439

3540
public void OnXamlRendered(FrameworkElement control)
3641
{
37-
var repeater = control.FindChildByName("WrapRepeater") as ItemsRepeater;
42+
var repeater = control.FindDescendantByName("WrapRepeater") as ItemsRepeater;
3843

3944
if (repeater != null)
4045
{
4146
repeater.ItemsSource = _items;
47+
48+
_wrapLayout = repeater.Layout as WrapLayout;
4249
}
50+
51+
_wrapScrollParent = control.FindDescendantByName("WrapScrollParent") as ScrollViewer;
4352
}
4453

4554
private class Item
@@ -52,5 +61,28 @@ private class Item
5261

5362
public Color Color { get; internal set; }
5463
}
64+
65+
private void SwitchButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
66+
{
67+
if (_wrapLayout != null && _wrapScrollParent != null)
68+
{
69+
if (_wrapLayout.Orientation == Orientation.Horizontal)
70+
{
71+
_wrapLayout.Orientation = Orientation.Vertical;
72+
ScrollViewer.SetVerticalScrollMode(_wrapScrollParent, ScrollMode.Disabled);
73+
ScrollViewer.SetVerticalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Disabled);
74+
ScrollViewer.SetHorizontalScrollMode(_wrapScrollParent, ScrollMode.Auto);
75+
ScrollViewer.SetHorizontalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Auto);
76+
}
77+
else
78+
{
79+
_wrapLayout.Orientation = Orientation.Horizontal;
80+
ScrollViewer.SetVerticalScrollMode(_wrapScrollParent, ScrollMode.Auto);
81+
ScrollViewer.SetVerticalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Auto);
82+
ScrollViewer.SetHorizontalScrollMode(_wrapScrollParent, ScrollMode.Disabled);
83+
ScrollViewer.SetHorizontalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Disabled);
84+
}
85+
}
86+
}
5587
}
5688
}

Microsoft.Toolkit.Uwp.UI.Controls.Layout/WrapLayout/WrapLayout.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,18 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size
254254
// for the last condition it is zeros so adding it will make no difference
255255
// this way is faster than an if condition in every loop for checking the last item
256256
totalMeasure.U = parentMeasure.U;
257+
258+
// Propagating an infinite size causes a crash. This can happen if the parent is scrollable and infinite in the opposite
259+
// axis to the panel. Clearing to zero prevents the crash.
260+
// This is likely an incorrect use of the control by the developer, however we need stability here so setting a default that wont crash.
261+
if (double.IsInfinity(totalMeasure.U))
262+
{
263+
totalMeasure.U = 0.0;
264+
}
265+
257266
totalMeasure.V = state.GetHeight();
258267

259268
totalMeasure.U = Math.Ceiling(totalMeasure.U);
260-
261269
return Orientation == Orientation.Horizontal ? new Size(totalMeasure.U, totalMeasure.V) : new Size(totalMeasure.V, totalMeasure.U);
262270
}
263271

0 commit comments

Comments
 (0)