For my treeview I have two different classes that provide the ItemsSource.
public class TreeViewModel : ViewModelBase
{
public ObservableCollection
As @sa_ddam213 said, you only need the HierarchicalDataTemplate
for NodeViewModel
, but the only problem with your code was the missing braces ({
and }
) for DataType="x:Type local:TreeViewModel"
in your data template definitions (it should be DataType="{x:Type local:TreeViewModel}"
). Adding brackets and ItemsSource
binding solves the problem:
The additional HierarchicalDataTemplate
for TreeViewModel
is not used, but it does not harm.
You should only have to declare the HierarchicalDataTemplate
for NodeViewModel
as this is the only thing showing in the TreeView
, and bind the actual ItemSource
to the TreeView
<TreeView ItemsSource="{Binding Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Full Example
Xaml:
<Window x:Class="WpfApplication13.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication13"
Title="MainWindow" x:Name="UI" Width="343" Height="744.625" >
<TreeView DataContext="{Binding ElementName=UI, Path=TreeModel}" ItemsSource="{Binding Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Window>
Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public TreeViewModel TreeModel
{
get
{
return new TreeViewModel
{
Items = new ObservableCollection<NodeViewModel>{
new NodeViewModel { Name = "Root", Children = new ObservableCollection<NodeViewModel> {
new NodeViewModel { Name = "Level1" , Children = new ObservableCollection<NodeViewModel>{
new NodeViewModel{ Name = "Level2"}}} } }}
};
}
}
}
public class TreeViewModel
{
public ObservableCollection<NodeViewModel> Items { get; set; }
}
public class NodeViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public ObservableCollection<NodeViewModel> Children { get; set; }
}
Result: