#1,217 – Using Multiple HierarchicalDataTemplates in a TreeView

I showed last time how to use a HierarchicalDataTemplate as the ItemTemplate for a TreeView. This allowed us to specify the look and feel of each node in the tree and also dictated how the main data item would be traversed to generate the tree.

If you have some hierarchical data in which the items are not all of the same type, you can specify more than one HierarchicalDataTemplate for the TreeView, based on the underlying type of each node.

Let’s assume that we have both a Breed and a Dog class. Breed objects contain information about a breed and in turn have a Dogs property that is a list of individual dogs of that breed.

In the example below, we have a TreeView whose ItemsSource is bound to a list of breeds. We then include a template to use for each Breed item and a different template to use for each Dog item in the tree. We also indicate that the tree should be expanded by looking at the Dogs property in each breed instance.

        <TreeView Grid.Row="0" Margin="5" ItemsSource="{Binding Breeds}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type loc:Breed}" ItemsSource="{Binding Dogs}">
                    <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
                        <TextBlock Text="Breed:"/>
                        <TextBlock Margin="5,0,0,0" FontWeight="Bold" Text="{Binding Name}"/>
                    </StackPanel>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate DataType="{x:Type loc:Dog}">
                    <StackPanel Orientation="Horizontal" Margin="0,2,0,0">
                        <TextBlock Text="{Binding}"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>

Note that we specify a DataType for each HierarchicalDataTemplate. As the tree is constructed, the appropriate template will be used, based on whether a node is a breed or a dog.

Below, we can see how this will look at runtime. Breed nodes show the breed’s name. Dog nodes show the dog’s name and age. We just have a TextBlock bound to the Dog instance as a whole, which causes the dog’s ToString method to get invoked. In our case, we’ve overridden ToString to display the dog’s name and age.

About Sean
Software developer in the Twin Cities area, passionate about .NET technologies. Equally passionate about my own personal projects related to family history and preservation of family stories and photos.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: