Search code examples
wpflistviewgroupingwpf-style

Share GroupStyle between ListViews


Is there a way to share code for GroupStyle/Columns between ListViews.

I have the settings working for one ListView, but since I want the same styling for two more, I don't want to copy the code, making the file cluttered. Plus one change in one of the ListViews, might be forgotten to be copied to the other.

I know that I can use styles in Window.Resources, and I made it work for columns, but the grouping I can't get to work.

I have the items loaded from ObservableCollection > ListCollectionView > ItemsSource with binding in PowerShell, working like a charm.

Xaml that works for one ListView:

<ListView Grid.Row="1" Name="lvAllFiles">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" Width="1000"/>
            <GridViewColumn DisplayMemberBinding="{Binding Created}" Header="Created" Width="100"/>
            <GridViewColumn DisplayMemberBinding="{Binding LastWriteTime}" Header="LastWriteTime" Width="100"/>
        </GridView>
    </ListView.View>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="ToolTip" Value="{Binding TT}"/>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Border BorderBrush="Gray" BorderThickness="1">
                                    <Expander IsExpanded="True">
                                        <Expander.Header>
                                            <TextBlock Text="{Binding Name}" Foreground="Gray" FontSize="14"/>
                                        </Expander.Header>
                                        <ItemsPresenter/>
                                    </Expander>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListView.GroupStyle>
</ListView>

Solution

  • Define the GroupStyle as resource with an x:Key, for example in <Window.Resources>:

    <Window.Resources>
        <GroupStyle x:Key="gs">
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Border BorderBrush="Gray" BorderThickness="1">
                                    <Expander IsExpanded="True">
                                        <Expander.Header>
                                            <TextBlock Text="{Binding Name}" Foreground="Gray" FontSize="14"/>
                                        </Expander.Header>
                                        <ItemsPresenter/>
                                    </Expander>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </Window.Resources>
    

    You can then reference it like this:

    <ListView Grid.Row="1" Name="lvAllFiles">
        ...
        <ListView.GroupStyle>
            <StaticResource ResourceKey="gs" />
        </ListView.GroupStyle>
    </ListView>