For my treeview I have two different classes that provide the ItemsSource.
public class TreeViewModel : ViewModelBase
{
public ObservableCollection<NodeViewModel> Items { get; set; }
}
public class NodeViewModel : ViewModelBase
{
public string Id { get; set; }
public string Name { get; set; }
public ObservableCollection<NodeViewModel> Children { get; set; }
}
Now I want my TreeView to display the Items in TreeViewModel and show hierarchical data as provided by the NodeViewModel.
Here is my XAML
<Window x:Class="TreeViewMasterDetails.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewMasterDetails"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TreeView Height="Auto"
HorizontalAlignment="Stretch"
Margin="10"
VerticalAlignment="Stretch"
Width="Auto">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="x:Type local:TreeViewModel" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="x:Type local:NodeViewModel" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
Have tried to provide Items
as the ItemsSource
of the TreeView
.
It does not show the data hierarchically, if displaying anything.
And I tried using the ItemTemplate
instead of the TreeView.Resources
, too.
What is wrong about it?
Perhaps a problem is the first TextBlock Text Binding
?
I want to display the Name
property of the NodeViewModel
in Items
there.
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:
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.
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