Set GridViewColumnHeader style from inside a ListView style

Christian Myksvoll picture Christian Myksvoll · Jan 4, 2012 · Viewed 16.2k times · Source

In one of my projects I have inherited a ListView and overridden the style by setting a new control template. I have also overridden the column header style. So far I have found two ways to do this:

1) By setting a style key and referencing the style in the GridView:

<Style TargetType="{x:Type GridViewColumnHeader}" x:Key="MyHeaderStyle">
    <Setter Property="Background" Value="Wheat" />
</Style>

<GridView ColumnHeaderContainerStyle="{StaticResource MyHeaderStyle}">

2) By not setting a style key for the above style. Now I don't need to reference the style in the GridView, BUT it also overrides ALL listview headers in my application independent of listview type.

Since I use many listviews in my application, I would like to accomplish this in a third and more flexible way; by setting the GridView.ColumnHeaderContainerStyle from inside a ListView style. That way I would not need to reference the header style in each GridView. Here is a simplified version of the XAML so far:

<Window.Resources>
    <Style TargetType="{x:Type GridViewColumnHeader}" x:Key="MyHeaderStyle">
        <Setter Property="Background" Value="Wheat" />
    </Style>

    <Style TargetType="{x:Type list:MyListView}">
        <Setter Property="GridView.ColumnHeaderContainerStyle" Value="{StaticResource MyHeaderStyle}" />            
        <Setter Property="Background" Value="Linen" />                                   
    </Style>
</Window.Resources>

<list:MyListView>
    <list:MyListView.View>
        <GridView>
            <GridViewColumn Header="Column1" />
            <GridViewColumn Header="Column2" />
        </GridView>
    </list:MyListView.View>
</list:MyListView>

This unfortunately does not set the header style... If I make this change to the XAML above, it works:

<GridView ColumnHeaderContainerStyle="{StaticResource MyHeaderStyle}">

Any ideas?

Answer

Christian Myksvoll picture Christian Myksvoll · Jan 5, 2012

Thanks snurre for pointing me in the right direction. I found a way to accomplish exactly what I wanted.

You don't need to place the Resources section within the ListView (that kind of custom tags for each ListView is what I wanted to get rid of in the first place). The Resources can be moved to the ListView style instead.

Here is the updated XAML that works exactly the way I want it to:

<Window.Resources>
    <Style TargetType="{x:Type GridViewColumnHeader}" x:Key="MyHeaderStyle">
        <Setter Property="Background" Value="Wheat" />
    </Style>

    <Style TargetType="{x:Type list:MyListView}">
        <Style.Resources>
            <Style TargetType="{x:Type GridViewColumnHeader}" BasedOn="{StaticResource MyHeaderStyle}" />
        </Style.Resources>

        <Setter Property="Background" Value="Linen" />                                   
    </Style>
</Window.Resources>

<list:MyListView>
    <list:MyListView.View>
        <GridView>
            <GridViewColumn Header="Column1" x:Name="col1" />
            <GridViewColumn Header="Column2" x:Name="col2" />
        </GridView>
    </list:MyListView.View>
</list:MyListView>