WPF TreeViewItem Background

How can I change the Background selected TreeViewItem when a TreeView (or application) loses focus. The selected item by default has a light gray background in this situation.

EDIT: attempt after the first answer: but the element with TargetName="Bd" will not be found.

 <TreeView> <TreeView.Resources> <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True"/> <Condition Property="IsSelectionActive" Value="False"/> </MultiTrigger.Conditions> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" /> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </TreeView.Resources> <TreeViewItem Header="Test1" IsExpanded="True"> <TreeViewItem Header="Test2" /> <TreeViewItem Header="Test3" /> <TreeViewItem Header="Test4" /> <TreeViewItem Header="Test5" /> </TreeViewItem> </TreeView> 
+2
background wpf focus treeviewitem
source share
3 answers

You need to change the default style for TreeViewItem . In particular, you need to change the following trigger:

 <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> ... <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> ... <ControlTemplate.Triggers> ... <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> ... </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> ... </Style> 

As you can see, the trigger sets the background {DynamicResource {x:Static SystemColors.ControlBrushKey}} if the element is focused and the selection is not active (the focus is somewhere else).

Update:

The full TreeViewItem style for the Aero theme is as follows:

 <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="Padding" Value="1,0,0,0"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TreeViewItem}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="19" Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" IsChecked="{Binding Path=IsExpanded,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/> <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsExpanded" Value="false"> <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/> </Trigger> <Trigger Property="HasItems" Value="false"> <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/> </Trigger> <Trigger Property="IsSelected" Value="true"> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> 

For this you will also need the following:

 <PathGeometry x:Key="TreeArrow"> <PathGeometry.Figures> <PathFigureCollection> <PathFigure IsFilled="True" StartPoint="0 0" IsClosed="True"> <PathFigure.Segments> <PathSegmentCollection> <LineSegment Point="0 6"/> <LineSegment Point="6 0"/> </PathSegmentCollection> </PathFigure.Segments> </PathFigure> </PathFigureCollection> </PathGeometry.Figures> </PathGeometry> <Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}"> <Setter Property="Focusable" Value="False"/> <Setter Property="Width" Value="16"/> <Setter Property="Height" Value="16"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToggleButton}"> <Border Width="16" Height="16" Background="Transparent" Padding="5,5,5,5"> <Path x:Name="ExpandPath" Fill="Transparent" Stroke="#FF989898" Data="{StaticResource TreeArrow}"> <Path.RenderTransform> <RotateTransform Angle="135" CenterX="3" CenterY="3"/> </Path.RenderTransform> </Path> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="ExpandPath" Property="Stroke" Value="#FF1BBBFA"/> <Setter TargetName="ExpandPath" Property="Fill" Value="Transparent"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="ExpandPath" Property="RenderTransform"> <Setter.Value> <RotateTransform Angle="180" CenterX="3" CenterY="3"/> </Setter.Value> </Setter> <Setter TargetName="ExpandPath" Property="Fill" Value="#FF595959"/> <Setter TargetName="ExpandPath" Property="Stroke" Value="#FF262626"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 

In all of this, you need to change only the part that interests you (the background color if the selection is inactive) and place these styles in the resources section in App.xaml in the main window.

+4
source share

An easier way for your particular case exists. As in the ListBox, you can replace the ControlBrush resource for the TreeViewItem using the style:

 <Style TargetType="TreeViewItem"> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}" Opacity=".4" /> </Style.Resources> </Style> 

You can specify any other color. Opacity is suggested because if you have multiple TreeView / ListBox, you can determine which one is focused. But of course, editing the full style can bring you more flexibility for future settings.

Example with gradients:

 <Style TargetType="TreeViewItem"> <Style.Resources> <LinearGradientBrush x:Key="{x:Static SystemColors.ControlBrushKey}" EndPoint='0 1'> <GradientStop Color='#AA00FF00' /> <GradientStop Offset='1' Color='#AA007700' /> </LinearGradientBrush> <LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint='0 1'> <GradientStop Color='#AA00FF00' /> <GradientStop Offset='1' Color='#AA007700' /> </LinearGradientBrush> </Style.Resources> </Style> 
+3
source share

If you do not want to override the default contol template, you can define your own template for headings using a text block and apply the style in this template to the text block itself (there is a small addition to the default TreeViewItem control template, so you should also set it to zero to achieve pixel perfection).

 <TreeView.Resources> <Style TargetType="TreeViewItem"> <Setter Property="Padding" Value="0"/> <Setter Property="HeaderTemplate"> <Setter.Value> <DataTemplate> <DataTemplate.Resources> <Style TargetType="TextBlock"> <Style.Triggers> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True"/> <Condition Binding="{Binding IsSelectionActive, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="False"/> </MultiDataTrigger.Conditions> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" /> </MultiDataTrigger> </Style.Triggers> </Style> </DataTemplate.Resources> <TextBlock Text="{Binding}"></TextBlock> </DataTemplate> </Setter.Value> </Setter> </Style> </TreeView.Resources> <TreeViewItem Header="Test1" IsExpanded="True"> <TreeViewItem Header="Test2" /> <TreeViewItem Header="Test3" /> <TreeViewItem Header="Test4" /> <TreeViewItem Header="Test5" /> </TreeViewItem> 

+1
source share

All Articles