Reputation: 623
I have built a WPF MVVM TreeView that shows different Elements.
BaseElement
- CatA
-- SubItemA
- CatB
-- SubItemB
Based on the class I would like to use a different data template. for each type.
So far I can connect to the selected Item, but I'm not sure how to manage the different data templates.
public class SubItem
{
public string Type { get; set; }
public string Name { get; set; }
}
<StackPanel Grid.Column="2" DataContext="{Binding ElementName=myTreeView, Path=SelectedItem}">
<TextBox Text="{Binding Parent.Name}" />
<TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
</StackPanel>
[Update Nov. 15]
<HierarchicalDataTemplate x:Key="L3Template" ItemsSource="{Binding L4Collection}" ItemTemplate="{StaticResource L4Template}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="CategoryTemplate" ItemsSource="{Binding L3Collection}" ItemTemplate="{StaticResource L3Template}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="L1Template" ItemsSource="{Binding CategoryCollection}" ItemTemplate="{StaticResource CategoryTemplate}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
[/Update Nov. 15]
Upvotes: 2
Views: 1270
Reputation: 623
Just in case it will help someone else:
<ContentPresenter Grid.Column="2" Content="{Binding ElementName=myTreeView, Path=SelectedItem}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:L1ViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:CategoryViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:L3ViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:L4ViewModel}">
<StackPanel>
<TextBox Text="{Binding Parent.Name}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
Upvotes: 1
Reputation: 726
Assuming that you named your classes L1Class, L3Class en Category and local points to the namespace of these classes:
<TreeView ...>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:L3Class}" ItemsSource="{Binding L4Collection}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding L3Collection}" >
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:L1Class}" ItemsSource="{Binding CategoryCollection}" >
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Note the use of the implicit datatemplates (no keys, but DataType!) in the resource section.
Upvotes: 2
Reputation: 726
If the subitems are different classes, then it is rather simple: add datatemplates foreach class to the resource section. If subitems need different templates based on the value of an enum prop, then you will need a datatemplateselector. This is a bit more cumbersome.
Upvotes: 3