Skip to content

Commit

Permalink
Fix crash with unbounded sizing for WrapLayout. (#3330)
Browse files Browse the repository at this point in the history
* 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) <24302614+michael-hawker@users.noreply.github.com>
  • Loading branch information
marcpems and michael-hawker authored Jun 6, 2020
1 parent 43c28eb commit 70ed20e
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 4 deletions.
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;
}

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

0 comments on commit 70ed20e

Please sign in to comment.