How to change the Background property of a selected TreeViewItem using Styles/Triggers

Jörg Debus 96 Reputation points
2021-03-28T15:34:50.26+00:00

Hi all,
I would like to change the Background color of selected items of ListViewItems. Many tries but no result. Only replacing the whole ControlTemplate works. This is brute force, which I want to avoid.

Any hint or a solution?

TIA
JD

Developer technologies | Windows Presentation Foundation
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2021-03-30T04:53:51.263+00:00

    Hi Uwe,
    you can set another colors for HighlightTextBrushKey and HighlightBrushKey in my previous demo:

    <TreeView ItemsSource="{Binding View}">  
      <TreeView.ItemContainerStyle>  
        <Style TargetType="{x:Type TreeViewItem}">  
          <Style.Resources>  
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="White" />  
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />  
          </Style.Resources>  
          <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />  
          <Setter Property="Background" Value="Transparent"/>  
          <Style.Triggers>  
            <DataTrigger Binding="{Binding IsSelected}" Value="True">  
              <Setter Property="Background" Value="Yellow"/>  
            </DataTrigger>  
          </Style.Triggers>  
        </Style>  
      </TreeView.ItemContainerStyle>  
      <TreeView.ItemTemplate>  
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">  
          <StackPanel Orientation="Horizontal">  
            <TextBlock VerticalAlignment="Center" Text="{Binding Name}" />  
          </StackPanel>  
        </HierarchicalDataTemplate>  
      </TreeView.ItemTemplate>  
    </TreeView>  
    

    82652-x.png

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,341 Reputation points
    2021-03-28T18:43:32.89+00:00

    Hi,
    you can use Trigger in ItemContainerStyle like in following demo:

    <Window x:Class="Window085"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1.WpfApp085"  
            mc:Ignorable="d"  
            Title="Window085" Height="450" Width="800">  
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
        <TreeView ItemsSource="{Binding View}">  
          <TreeView.ItemContainerStyle>  
            <Style TargetType="{x:Type TreeViewItem}">  
              <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />  
              <Setter Property="Background" Value="Transparent"/>  
              <Style.Triggers>  
                <DataTrigger Binding="{Binding IsSelected}" Value="True">  
                  <Setter Property="Background" Value="Yellow"/>  
                </DataTrigger>  
              </Style.Triggers>  
            </Style>  
          </TreeView.ItemContainerStyle>  
          <TreeView.ItemTemplate>  
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">  
              <StackPanel Orientation="Horizontal">  
                <TextBlock VerticalAlignment="Center" Text="{Binding Name}" />  
              </StackPanel>  
            </HierarchicalDataTemplate>  
          </TreeView.ItemTemplate>  
        </TreeView>  
      </Grid>  
    </Window>  
    

    And ViewModel:

    Imports System.Collections.ObjectModel  
    Imports System.ComponentModel  
      
    Namespace WpfApp085  
      Public Class ViewModel  
      
        Private ReadOnly col As New ObservableCollection(Of Data)  
        Private ReadOnly cvs As New CollectionViewSource  
      
        Public ReadOnly Property View As ICollectionView  
          Get  
            If cvs.Source Is Nothing Then GetData()  
            Return cvs.View  
          End Get  
        End Property  
      
        Private Sub GetData()  
          Dim rnd As New Random  
          For i = 1 To 100  
            Dim d As New Data With {.Name = $"Node {i}", .IsSelected = rnd.NextDouble > 0.5}  
            For k = 1 To 10  
              d.Children.Add(New Data With {.Name = $"Node {i} {k}", .IsSelected = rnd.NextDouble > 0.5})  
            Next  
            col.Add(d)  
          Next  
          cvs.Source = col  
        End Sub  
      End Class  
      
      Public Class Data  
        Public Property Name As String  
        Public Property IsExpanded As Boolean = True  
        Public Property IsSelected As Boolean  
        Public Property Children As New ObservableCollection(Of Data)  
      End Class  
      
    End Namespace  
    

    Result:

    82126-x.png


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.