I want to display some objects in a treeview, but so far unfortunately without success.
I've a ObservableCollection <ICustom>
of objects: Settings.ListOfCustomers
The interface of the object ICustom
:
int Id { get; }
int age { get; }
CustomerType CustomerType { get; }
ObservableCollection<IValue> ListOfValues { get; }
The ObservableCollection<IValue> ListOfValues
has also some properties like:
String Name { get; }
My View:
<TreeView ItemsSource="{Binding ListOfCustomers, UpdateSourceTrigger=PropertyChanged}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type customerConfig:ICustomer}">
<TextBlock Text="{Binding Id}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type valueConfig:IValue}" ItemsSource="{Binding ListOfValues}">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Question: How can I display display these objects in a TreeView? My approach (see "My View") does not work.
To Question 1: ObservableCollections
have the advantage, that all notifications to the view are done automatically. So you do not have to worry about NotifyPropertyChanged
events for adding/removing objects from the collection.
To Question 2: Your ViewModel
is your DataContext
? I do not see where there is a property ObservableCollection<ICustomer>
? Can you provide more detail about relationships in this classes?
EDIT:
Based on the answer of mm8, the x:Type attribute should be of a concrete type. So the code should look something like this:
I suggest that you have an ObservableCollection<ICustomer> ListOfCustomers
in your ViewModel
, then you can bind in the view:
<TreeView ItemsSource="{Binding ListOfCustomers}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type Customer}">
<TextBlock Text="{Binding Id}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type modSettings:Value}"
ItemsSource="{Binding ListOfValues}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
I think this thread provides a more detailed solution for your problem: Implement WPF treeview with different Parent Nodes a well as different child nodes?
EDIT2:
I changed my code a bit, to match your requirements. This should display all nodes:
<TreeView ItemsSource="{Binding ListOfCustomers}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ListOfValues}" DataType="{x:Type Customer}">
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type modSettings:Value}">
<TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<TextBlock Text="{Binding Path=Id}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
I have converted all Lists to
ObservableCollection
, also the nested Lists. Is this necessary and correct?
It is not necessary unless you intend to add items to the collection dynamically at runtime. Then you need to use an ObservableCollection<T>
for these to automatically show up in the TreeView
. Othwerwise you might as well use a List<T>
.
How can I display display these objects in a
TreeView
?
You get the error message because you add the templates to the Items
property of the TreeView
. They should be added to the Resources
property, i.e. you need to add a <TreeView.Resources>
element.
You should also read this:
Why can't a DataTemplate bind to an interface when that DataTemplate was explicitly returned from a DataTemplateSelector?
Templates with the DataType
property set to an interface type are not applied. So you should either define a HierarchicalDataTemplate
per concrete type or use a DataTemplateSelector
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With