WPF TreeView HierarchicalDataTemplate - binding to object with different child collections

旧街凉风 提交于 2019-12-01 08:00:18

It is a bit complicated since your tree has two different child collections. WPF does not support a scenario with multiple ItemsSource definitions. Therefore you need to combine those collection into a CompositeCollection. The type matching of the composite elements (i.e. Car, Book) will be done automatically.

In XAML you need to define so-called HierarchicalDataTemplates that match your type definitions. If local points to the namepace where Book, Car and Person are defined, the simplified HierarchicalDataTemplates could look like this:

 <HierarchicalDataTemplate DataType="{x:Type local:Person}" 
                              ItemsSource="{Binding CompositeChildren}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="{x:Type local:Book}">
        <TextBlock Text="{Binding Path=Title}" />
        <!-- ... -->
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="{x:Type local:Car}">
        <TextBlock Text="{Binding Path=Model}" />
        <!-- ... -->
    </HierarchicalDataTemplate>

Then you need to hook up your collection to the tree control. There are a few possibilities to do this, the easiest would be to define a property in your Window class and define a Binding:

<TreeView Items={Binding ElementName=myWindow, Path=Persons}/>

This should point you into the right direction, but don't take my code as compile ready :-)

Robert Rossney

CompositeCollection is a good answer, except you can't bind the child collections to the DataContext because it's not a Freezable. You can only bind them to resources. (See this question for more on that.) That makes it kind of hard to use in a HierarchicalDataTemplate, since the ItemsSource in one needs to bind to a property in the current context to be useful.

If you don't need change notification on the collections, you can easily implement a property in your view model, e.g.:

public IEnumerable<object> Items
{
   get { return Books.Concat(Cars); }
}

If you need change notification on the collection, it's a lot less trivial.

You need a DataTemplate, otherwise WPF doesn't know how to display your object.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!