Search code examples
wpfxamllistboxresourcedictionaryexpander

Using xaml resources, but keeping unique content per reference


I have several ListBoxes and have set up the group style to make the groups expanders. I want all of the ListBoxes to use the same style information to make them all expanders, but i want to be able to change the content of the header to be custom for each use of the style.

Is there any way i can take the out of the but still edit the contents of the

Currently, i am using a syntax similar to this:

<ListBox x:Name="listBox1" ItemsSource="{Binding}" Height="571" Width="260">

        <ListBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander IsExpanded="True" Style="{StaticResource GroupBoxExpander}">
                                        <Expander.Header>

                                            <Grid Width="190" Background="Yellow">

                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="40" />
                                                    <ColumnDefinition Width="40" />
                                                </Grid.ColumnDefinitions>

                                                <TextBlock Grid.Column="0" Text="Count:" />
                                                <TextBlock Grid.Column="1" Text="{Binding Path=ItemCount}" />

                                            </Grid>

                                        </Expander.Header>
                                        <Expander.Content>
                                            <ItemsPresenter Margin="15,0,0,0"></ItemsPresenter>
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </ListBox.GroupStyle>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <local:ItemControl1 />
            </DataTemplate>
        </ListBox.ItemTemplate>

    </ListBox>

Any help greatly appreciated!

Thanks for reading


Solution

  • GroupItem is a ContentControl, so you could use the same Template with a different ContentTemplate. Separate your style out like this:

    <Style TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                    <Expander IsExpanded="True" >
                        <Expander.Header>
                            <ContentPresenter/>
                        </Expander.Header>
                        <Expander.Content>
                            <ItemsPresenter Margin="15,0,0,0"></ItemsPresenter>
                        </Expander.Content>
                    </Expander>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid Width="190" Background="Yellow">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition Width="40" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="Count:" />
                        <TextBlock Grid.Column="1" Text="{Binding Path=ItemCount}"/>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    The ContentPresenter in the ControlTemplate will instantiate the DataTemplate, so this will have the same appearance, but you can customize the header by replacing the DataTemplate. You could create a base style with the ControlTemplate, and then create other styles based on that one that re-use the ControlTemplate but have a different DataTemplate.

    <Style TargetType="{x:Type GroupItem}"
           x:Key="BaseGroupStyle">
        <Setter Property="Template" .../>
    </Style>
    <Style TargetType="{x:Type GroupItem}"
           BasedOn="{StaticResource BaseGroupStyle}"
           x:Key="CountGroupStyle">
        <Setter Property="ContentTemplate" .../>
    </Style>