Reputation: 7997
In WPF, when you have a ListView
passing over an item with the mouse will give a nice highlight effect, like this:
However, this doesn't happen with a TreeView
. My question is simple: how do I enable the same effect for the items in a TreeView
?
NOTE: I'm aware of these questions: WPF TreeView Highlight Row On Hover Highlight whole TreeViewItem line in WPF
But they are mainly concerned with extending the highlight behavior to the entire row, while I still can't figure out how to enable the highlight effect on a single TreeViewItem
(that would be more than enough for me)
Upvotes: 0
Views: 10046
Reputation: 63377
Normally we can add some style for the TreeViewItem
with some Trigger to toggle the Background on mouse over. However it's not such simple when TreeViewItem
contains each other (nested) and the bubbling of the event will cause some unwanted effect. I've tried digging in solving the problem with this approach but no luck (just nearly solve it but not perfectly).
So we have to use another approach, here we will change the template of the Header by setting the HeaderTemplate
of TreeViewItem
. In that template, we will add triggers such as for the root Border and then everything works OK:
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Border>
<TextBlock Text="{Binding}"/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self},
Path=IsMouseOver}" Value="True"/>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem},
Path=IsSelected}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="#ffe5f3fb"/>
<Setter Property="BorderBrush" Value="#ffa5d7f0"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
<TreeViewItem Header="Item 1">
<TreeViewItem Header="Item 11"></TreeViewItem>
<TreeViewItem Header="Item 12"/>
</TreeViewItem>
<TreeViewItem Header="Item 2">
</TreeViewItem>
</TreeView>
Note that you can create whatever Brush
you like to replace the simple SolidColorBrush
I used above for the Background
. You should read more about Brush
in WPF.
Update: As far as I know to synchronize with the System settings about colors and brushes, we just have the static class SystemColors
. The closest color I've found for the hovering highlight is SystemColors.HotTrackColorKey
. However I guess the hovering highlight used for the ListView
in Windows 7 applies some opacity for the brush and it looks lighter. So I've tried using the opacity of 0.05
for the brush and it looks fairly close to the default highlight color of ListView in Windows 7. You can define the brush in the resource and use it like this:
//inside the Style for Border
<Style.Resources>
<SolidColorBrush x:Key="hoverBrush" Opacity=".05"
Color="{DynamicResource {x:Static SystemColors.HotTrackColorKey}}"/>
</Style.Resources>
Then set the brush for background via Setter
:
<Setter Property="Background" Value="{DynamicResource hoverBrush}"/>
Upvotes: 7