Change TreeViewItem background based on an attached property
-
18-04-2021 - |
Question
I am trying to change the background of the TreeViewItems in a TreeView, based on an a property (boolean) attached to the TreeViewItems. I've tried this :
<local:BooleanToBrushConverter x:Key="BooleanToBrushConverter"
TrueBrush="Yellow" FalseBrush="Transparent"/>
<local:TreeViewEx ItemsSource="{Binding Items}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
<Setter Property="Background" Value="{Binding Path=(local:TreeViewItemExtensions.Selected),
RelativeSource={RelativeSource Self},
Converter={StaticResource BooleanToBrushConverter}}"/>
<TreeView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Green"/>
</TreeView.Resources>
...
</local:TreeViewEx>
Ran the app, but although I've (programatically) set the property (Selected, not to be confused with IsSelected) to true on the "Child" TreeViewItem the background was not set
I've taken a look with Snoop and found that it doesn't have the yellow background as it should (the converter fires and returns correctly) :
However, taking a peek in Snoop it shows that the Yellow brush has been applied to that TreeViewItem :
However if I manually set the background to the parent Stackpanel ([016] in Snoop) it reflects that value. But I can't get to it by the style..
Any ideas?
UPDATE : It seems that the currently selected item has some kind of style that needs addressing somehow..
Solution
The problem results from the fact that TreeView.ItemContainerStyle only applies to the root item. If you replace TreeView.ItemContainerStyle by a default style for TreeViewItem in TreeView.Resources you get a style that applies to all items (in that TreeView):
<TreeView>
<TreeView.Resources>
<!-- default style instead of ItemContainerStyle -->
<Style TargetType="TreeViewItem">
<Setter Property="Background"
Value="{Binding Path=(local:TreeViewItemExtensions.Selected),
RelativeSource={RelativeSource Self},
Converter={StaticResource BooleanToBrushConverter}}"/>
</Style>
</TreeView.Resources>
<TreeViewItem Header="Root" IsExpanded="True">
<TreeViewItem Header="Child"/>
<TreeViewItem Header="Child" Name="testChild"/>
<TreeViewItem Header="Child"/>
</TreeViewItem>
</TreeView>
Now setting the Selected attached property works:
TreeViewItemExtensions.SetSelected(testChild, true);