Search code examples
c#wpfenumstreeview

WPF TreeView - Apply styling based on enum value


I have a TreeView bound to an ObservableCollection containing enum values:

public enum Categories
{
    CatA, CatB, CatC, CatD
}

public ObservableCollection<Categories> CategoriesList = new ObservableCollection<Categories>();

foreach (Categories cat in (Categories[])Enum.GetValues(typeof(Categories)))
{
    CategoriesList.Add(cat);
}

The TreeView is bound to CategoriesList:

tvCat.ItemsSource = CategoriesList;

The the XAML markup:

<TreeView x:Name="tvCat">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                 <Trigger Property="IsSelected" Value="True">
                     <Setter Property="FontWeight" Value="Bold"/>
                 </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

I am trying to figure out how to apply individual stying to TreeViewItem for each enum value, e.g. blue color for CatA, red color for CatB, may be an icon for CatC etc.

Thanks a lot for any help.


Solution

  • You can use DataTriggers to get the desired output.

    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="FontWeight" Value="Bold"/>
                </Trigger>
                <DataTrigger Binding="{Binding}" Value="CatA">
                    <Setter Property="Foreground" Value="Blue" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="CatB">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
    

    EDIT

    The above XAML is if you just want a different color for your Items. If you also want to have different content (e.g. an icon for CatC), then you'd have to set the ControlTemplate based on a DataTrigger.

    Here is the XAML to achieve that.

    <TreeView.Resources>
        <ControlTemplate TargetType="TreeViewItem" x:Key="CatCTemplate">
            <Image Source="icon.jpeg" Height="64" Width="64" />
        </ControlTemplate>
    </TreeView.Resources>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="FontWeight" Value="Bold"/>
                </Trigger>
                <DataTrigger Binding="{Binding}" Value="CatA">
                    <Setter Property="Foreground" Value="Blue" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="CatB">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding}" Value="CatC">
                    <Setter Property="Template" Value="{StaticResource CatCTemplate}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>