Windows 10 Grouped VariableSizedWrapGrid similar to Windows 8

Tags: Windows 10, XAML

When porting one of our existing apps from Windows 8.1 to Windows 10, we ran into the issue where our grouped VariableSizedWrapGrid did not wrap correctly and each group consisted out of a single column running out of the screen borders (the groups were placed horizontally to keep the same behavior as Windows 8.1 for this particular app). The non-grouped VariableSizedWrapGrid implementations were all fine. After spending several hours tweaking and trying, I decided to start from scratch in a separate app. And of course … everything worked fine on the first try, not much later the implementation in our app was fixed as well.

First of all, you need your own custom control derived from GridView to handle setting the Row and Column spans.

public class VariableSizedGridView : GridView
{
    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        dynamic model = item; // alternative is implement an interface with both properties
        try
        {
            element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, model.ColSpan);
            element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, model.RowSpan);
        }
        catch
        {
            element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.ColumnSpanProperty, 1);
            element.SetValue(Windows.UI.Xaml.Controls.VariableSizedWrapGrid.RowSpanProperty, 1);
        }
        finally
        {
            element.SetValue(VerticalContentAlignmentProperty, VerticalAlignment.Stretch);
            element.SetValue(HorizontalContentAlignmentProperty, HorizontalAlignment.Stretch);
            base.PrepareContainerForItemOverride(element, item);
        }
    }
}

We then use this control in XAML and set the layout and scrolling behavior to horizontal to keep our app in line with the Windows 8.1 behavior. We have already done this in the post on SemanticZoom.

<!-- Horizontal scrolling to be like 8.1 for demo purposes -->
<controls:VariableSizedGridView x:Name="Grouped" Grid.Row="1" Visibility="Collapsed"
          ItemsSource="{Binding Source={StaticResource Collection}}"
          ItemTemplate="{StaticResource MyItemTemplate}"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.HorizontalScrollMode="Auto"
          ScrollViewer.VerticalScrollBarVisibility="Disabled"
          ScrollViewer.VerticalScrollMode="Disabled">

    <controls:VariableSizedGridView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </controls:VariableSizedGridView.ItemsPanel>

    <controls:VariableSizedGridView.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" Margin="0">
                        <TextBlock Text='{Binding Name}' Foreground="Gray" FontSize="25" Margin="5" />
                    </Grid>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
            <GroupStyle.Panel>
                <ItemsPanelTemplate>
                    <VariableSizedWrapGrid Orientation="Vertical" ItemWidth="300" ItemHeight="150" />
                </ItemsPanelTemplate>
            </GroupStyle.Panel>
        </GroupStyle>
    </controls:VariableSizedGridView.GroupStyle>
</controls:VariableSizedGridView>

VariableSizedWrapGrid

The code for this blog post is available on GitHub. As a bonus there's also a non-grouped VariableSizedWrapGrid implementation in de sample.

Note: When porting an app from Windows 8.1 to Windows 10, please review used styles or even better reset the styles and re-apply any changes made to get the most out of the improvements the Windows team made.

Comments

comments powered by Disqus