Should be simple and common enough: I want to override the hover color on a GridView ColumnHeader.
So I'm using <GridView.ColumnHeaderContainerStyle >
, a <Trigger>
and a <Setter>
, but it's completely ignored. It should be an ugly green, but no, it's some bluish color.
The Trigger is working though, if I add a Foreground property Setter, it does work.
What am I missing?
<ListView ...>
...
<ListView.View>
<GridView AllowsColumnReorder="False" >
<GridView.ColumnHeaderContainerStyle >
<Style TargetType="{x:Type GridViewColumnHeader}" >
<Setter Property="Background" Value="{StaticResource MahApps.Brushes.Gray10}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"></Setter>
<Setter Property="Foreground" Value="Blue"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Header="NOT GREEN" Width="150" />
</GridView>
</ListView.View>
...
</ListView>
Edit: I did some snooping, and I could track a ControlTemplate trigger on MouseOver that seems to take precedence. However, looking at the doc (https://learn.microsoft.com/en-us/dotnet/desktop/wpf/properties/dependency-property-value-precedence?view=netdesktop-7.0&redirectedfrom=MSDN), I'm unsure which is what in the order of precedence
- Local values.
- TemplatedParent
- Implicit styles.
- Style triggers.
- Template triggers.
- Style setter values.
According to this, I would have believed that my style trigger would take precedence over the ControlTemplate Trigger
You will need to override the Style
for the GridViewColumnHeader.Template
, since that manages the background via other properties. The document linked below has all the xaml used to build out the control, so you can see why setting the background of the header doesn't help. The core issue is that the hover is set by the VisualStateGroup
and not the template binding. So effectively that is overriding whatever MouseOver triggers you are setting.
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/listview-styles-and-templates?view=netframeworkdesktop-4.8
Here is an example of that, leveraging the template provided in Microsoft's docs and modifying that for your needs, you might end up with something like what I have below. Note that this might be missing things from the built-in control, but you can add those back by just starting with what Microsoft has in the document linked above.
<ListView>
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Background"
Value="Gray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="HeaderContent"
Margin="0,0,0,1"
RecognizesAccessKey="True"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="Stretch"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Thumb x:Name="PART_HeaderGripper"
HorizontalAlignment="Right"
Margin="0,0,-9,0"
Style="{StaticResource GridViewColumnHeaderGripper}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="Green"></Setter>
<Setter Property="Foreground"
Value="Blue"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Header="NOT GREEN"
Width="150" />
</GridView>
</ListView.View>
</ListView>
Since we are overriding the entire control, we need to add back the default Thumb
(i.e. the column resizing grip) as such:
<Window.Resources>
<Style x:Key="GridViewColumnHeaderGripper"
TargetType="Thumb">
<Setter Property="Width"
Value="18" />
<Setter Property="Background"
Value="Black">
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}"
Background="Transparent">
<Rectangle HorizontalAlignment="Center"
Width="1"
Fill="LightGray" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>