Search code examples
wpfxamltreeviewdatatemplatedatatrigger

Dynamically set image of each node


So I have 3 levels of nodes in my TreeView:

  • A single Root Node (should display Image1.png)
  • Some second level nodes (should display Image2.png)
  • Each second level node has some third-level nodes (should display Image3.png)

I'm trying to use a DataTemplate to dynamically assign the display image to each node, depending upon its level. Since level is not as easily available in WPF as it is in WinForms, I simply resorted to using Tag property of TreeViewItems to store their level. Then I wrote this following Style for assigning display images:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="HeaderTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image Name="img" Width="20" Height="20" Stretch="Fill">
                        <Image.Style>
                            <Style TargetType="{x:Type Image}">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Tag}" Value="0">
                                        <Setter Property="Source" Value="Icons\Image1.png"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Tag}" Value="1">
                                        <Setter Property="Source" Value="Icons\Image2.png"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Image.Style>
                    </Image>
                    <TextBlock VerticalAlignment="Center" Text="{Binding}" Margin="5,0" />
                </StackPanel>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Yes, you guessed it; it doesn't work. Can someone please identify where the problem lies? Or am I doing it just the wrong way?


Solution

  • Right now, your {Binding Tag} will try to find the Tag property of the TreeViewItem's DataContext, not the DependencyProperty. And since, i'm guessing, there is no Tag property in the DataContext, it won't work. If you look at your output Windows in VS, you should see binding errors all over the place.

    What you need to do is add the relative source to your binding so it looks at the TreeViewItem instead of the DataContext. Here is an example :

    <DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}" Value="0">