I am trying to bind a collection to wpf TreeView
control using data templates. Each item(Person) in the collection also contains two different collections(Cars,
You need a DataTemplate
, otherwise WPF doesn't know how to display your object.
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 :-)
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.