Search code examples
wpflistviewgroupingdatatemplateitemspaneltemplate

How to display groups in a ListView inside a horizontal StackPanel?


I have a ListView which is used to display items with one level of grouping, but I did not manage to show groups in a horizontal StackPanel, I've set the template of the ListView, its ItemsPanel property, its ItemTemplate property and its GroupStyle property but it does not show up as in the image below.

I've read this post and I did not understand how to apply the knowledge in my case.

XAML

<SolidColorBrush x:Key="ListBox.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ListBox.Static.Border" Color="#FFABADB3"/>
<SolidColorBrush x:Key="ListBox.Disabled.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ListBox.Disabled.Border" Color="#FFD9D9D9"/>
<Style x:Key="ListViewStyle1" TargetType="{x:Type ListView}">
    <Setter Property="Background" Value="{StaticResource ListBox.Static.Background}"/>
    <Setter Property="BorderBrush" Value="{StaticResource ListBox.Static.Border}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListView}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
                    <ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
                        <StackPanel Orientation="Horizontal">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </StackPanel>
                    </ScrollViewer>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource ListBox.Disabled.Border}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsGrouping" Value="true"/>
                            <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

(irrelevant markup here, then:)

<ListView Background="Green"
    Foreground="White" VerticalAlignment="Center"
    ItemsSource="{x:Static local:GameLevels.Levels}" Name="LevelsListBox" HorizontalAlignment="Center" Style="{DynamicResource ListViewStyle1}">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid HorizontalAlignment="Left" VerticalAlignment="Top">
            </UniformGrid>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" TextAlignment="Center"></TextBlock>
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Padding="5,0,0,0" FontWeight="Bold" FontSize="14" Text="{Binding Name}" Visibility="{Binding Name, Converter={StaticResource IsGroupTitleInChapter0Conv}}"/>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </ListView.GroupStyle>
</ListView>

Code-behind

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(LevelsListBox.ItemsSource);
PropertyGroupDescription gd = new PropertyGroupDescription("Category");
view.GroupDescriptions.Add(gd);

Actual screenshot

actual

Intended screenshot

expected


Solution

  • You should set the Panel property of the GroupStyle:

    <ListView Background="Green"
        Foreground="White" VerticalAlignment="Center"
        ItemsSource="{x:Static local:GameLevels.Levels}" Name="LevelsListBox" HorizontalAlignment="Center">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" TextAlignment="Center"></TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Padding="5,0,0,0" FontWeight="Bold" FontSize="14" Text="{Binding Name}" Visibility="{Binding Name, Converter={StaticResource IsGroupTitleInChapter0Conv}}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>