xamlwinui-3winuiwindows-app-sdk

WinUI 3 ItemsView with LinedFlowLayout items shrinking instead of wrapping


I have an ItemsView control with LinedFlowLayout inside my WinUI 3 application. I would like to make a list of "tags", but for some reason I cannot figure out, when the window is resized instead of wrapping whenever there isn't enough space in the line the items start shrinking by a little before actually wrapping.

Page xaml:

<ItemsView Grid.Row="1" ItemsSource="{x:Bind ViewModel.Tags}">
    <ItemsView.ItemTemplate>
        <DataTemplate x:DataType="local:Tag">
            <ItemContainer>
                <Border BorderThickness="1" BorderBrush="Black" CornerRadius="12" Padding="8,2">
                    <StackPanel Orientation="Horizontal" Spacing="4" Width="Auto">
                        <TextBlock Text="{x:Bind TagName}"/>
                        <AppBarSeparator/>
                        <TextBlock Text="{x:Bind WordCount}"/>
                    </StackPanel>
                </Border>
            </ItemContainer>
        </DataTemplate>
    </ItemsView.ItemTemplate>
    <ItemsView.Layout>
        <LinedFlowLayout LineSpacing="8" MinItemSpacing="8"/>
    </ItemsView.Layout>
</ItemsView>

Here is how the "shrinking" looks like: Lined Flow Layout items shrinking

I have tried various changes to the data template items including reducing them to the bare minimum - a single text block. Also different collections, but none of the combinations yielded the desired result. I would like for my items to just wrap to the next line whenever they are out of space instead of shrinking.


Solution

  • Unfortunately, it seems that LinedFlowLayout will try to resize the items. As a workaround, updating the ItemContainer's MinWidth should help:

    <ItemsView.ItemTemplate>
        <DataTemplate x:DataType="local:Tag">
            <ItemContainer SizeChanged="TagItemContainer_SizeChanged">
                <Border
                    Padding="8,2"
                    BorderBrush="Black"
                    BorderThickness="1"
                    CornerRadius="12">
                    <StackPanel
                        Width="Auto"
                        Orientation="Horizontal"
                        Spacing="4">
                        <TextBlock Text="{x:Bind TagName}" />
                        <AppBarSeparator />
                        <TextBlock Text="{x:Bind WordCount}" />
                    </StackPanel>
                </Border>
            </ItemContainer>
        </DataTemplate>
    </ItemsView.ItemTemplate>
    
    private void TagItemContainer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (sender is not FrameworkElement element)
        {
            return;
        }
    
        element.MinWidth = Math.Max(element.MinWidth, element.ActualWidth);
    }