Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash with unbounded sizing for WrapLayout. #3330

Merged
merged 7 commits into from
Jun 6, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public StaggeredLayoutPage()

public void OnXamlRendered(FrameworkElement control)
{
var repeater = control.FindChildByName("StaggeredRepeater") as ItemsRepeater;
var repeater = control.FindDescendantByName("StaggeredRepeater") as ItemsRepeater;

if (repeater != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<Grid Padding="48">
<winui:ItemsRepeaterScrollHost> <!-- Needed for 1803 and below -->
<ScrollViewer>
<ScrollViewer x:Name="WrapScrollParent">
<winui:ItemsRepeater x:Name="WrapRepeater"
Background="{ThemeResource Brush-Grey-04}"
ItemTemplate="{StaticResource WrapTemplate}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:winui="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Page.Resources>
<controls:WrapLayout x:Key="WrapLayoutPlaceholder"/>
</Page.Resources>

<winui:ItemsRepeaterScrollHost>
<ScrollViewer x:Name="WrapScrollParent">
<winui:ItemsRepeater x:Name="WrapRepeater"/>
</ScrollViewer>
</winui:ItemsRepeaterScrollHost>
</Page>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Collections.ObjectModel;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.Toolkit.Uwp.UI.Extensions;
using Microsoft.UI.Xaml.Controls;
using Windows.UI;
Expand All @@ -19,11 +20,15 @@ public sealed partial class WrapLayoutPage : Page, IXamlRenderListener
{
private ObservableCollection<Item> _items = new ObservableCollection<Item>();
private Random _random;
private ScrollViewer _wrapScrollParent;
private WrapLayout _wrapLayout;

public WrapLayoutPage()
{
this.InitializeComponent();

SampleController.Current.RegisterNewCommand("Switch Orientation", SwitchButton_Click);

_random = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < _random.Next(1000, 5000); i++)
{
Expand All @@ -34,12 +39,16 @@ public WrapLayoutPage()

public void OnXamlRendered(FrameworkElement control)
{
var repeater = control.FindChildByName("WrapRepeater") as ItemsRepeater;
var repeater = control.FindDescendantByName("WrapRepeater") as ItemsRepeater;

if (repeater != null)
{
repeater.ItemsSource = _items;

_wrapLayout = repeater.Layout as WrapLayout;
}

_wrapScrollParent = control.FindDescendantByName("WrapScrollParent") as ScrollViewer;
}

private class Item
Expand All @@ -52,5 +61,28 @@ private class Item

public Color Color { get; internal set; }
}

private void SwitchButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
if (_wrapLayout != null && _wrapScrollParent != null)
{
if (_wrapLayout.Orientation == Orientation.Horizontal)
{
_wrapLayout.Orientation = Orientation.Vertical;
ScrollViewer.SetVerticalScrollMode(_wrapScrollParent, ScrollMode.Disabled);
ScrollViewer.SetVerticalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Disabled);
ScrollViewer.SetHorizontalScrollMode(_wrapScrollParent, ScrollMode.Auto);
ScrollViewer.SetHorizontalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Auto);
}
else
{
_wrapLayout.Orientation = Orientation.Horizontal;
ScrollViewer.SetVerticalScrollMode(_wrapScrollParent, ScrollMode.Auto);
ScrollViewer.SetVerticalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Auto);
ScrollViewer.SetHorizontalScrollMode(_wrapScrollParent, ScrollMode.Disabled);
ScrollViewer.SetHorizontalScrollBarVisibility(_wrapScrollParent, ScrollBarVisibility.Disabled);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,18 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size
// for the last condition it is zeros so adding it will make no difference
// this way is faster than an if condition in every loop for checking the last item
totalMeasure.U = parentMeasure.U;

// Propagating an infinite size causes a crash. This can happen if the parent is scrollable and infinite in the opposite
// axis to the panel. Clearing to zero prevents the crash.
// This is likely an incorrect use of the control by the developer, however we need stability here so setting a default that wont crash.
if (double.IsInfinity(totalMeasure.U))
{
totalMeasure.U = 0.0;
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
}

totalMeasure.V = state.GetHeight();

totalMeasure.U = Math.Ceiling(totalMeasure.U);

return Orientation == Orientation.Horizontal ? new Size(totalMeasure.U, totalMeasure.V) : new Size(totalMeasure.V, totalMeasure.U);
}

Expand Down