In a WPF project I have created a a Treeview that should display items from an ObservableCollection and just one generation of children. However, the Treeview shows only the parent objects, but not even their Name, let alone children. It simply shows "WpfTreeViewInPlaceEdit.MVVM.Model.TreeViewParentItem".
Here is my xaml:
<UserControl x:Class="WpfTreeViewInPlaceEdit.MVVM.View.WpfTreeViewInPlaceEditControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfTreeViewInPlaceEdit.MVVM.View"
xmlns:model="clr-namespace:WpfTreeViewInPlaceEdit.MVVM.Model"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Name="wpfTreeViewInPlaceEditControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="TextBlock" />
<TreeView x:Name="treeView" ItemsSource="{Binding TRVItems}" Grid.Row="1">
<TreeView.Resources>
<HierarchicalDataTemplate x:Key="trvParents" DataType="{x:Type model:TreeViewParentItem}" ItemsSource="{Binding Path=TreeViewChildrenItems}">
<Grid>
<!-- Normal state of the header -->
<TextBlock x:Name="textBlockHeader" Text="{Binding Path=Name, Mode=TwoWay}" Margin="3,0" MouseLeftButtonDown="textBlockHeaderSelected_MouseLeftButtonDown"/>
</Grid>
</HierarchicalDataTemplate>
<DataTemplate x:Key="trvChildren" DataType="{x:Type model:TreeViewChildItem}">
<StackPanel Orientation="Horizontal">
<TextBlock Name="TextBlockLabel" Text="{Binding Path=Name}"/>
<TextBlock Text="TEST"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>
The corresponding ViewModel:
namespace WpfTreeViewInPlaceEdit.MVVM.ViewModel
{
class TreeViewViewModel: ViewModelBase
{
public TreeViewViewModel()
{
TRVItems = new ObservableCollection<TreeViewParentItem>()
{
new TreeViewParentItem("First parent item"),
new TreeViewParentItem("Second parent item"),
new TreeViewParentItem("Third parent item")
};
}
private ObservableCollection<TreeViewParentItem> _TRVItems;
public ObservableCollection<TreeViewParentItem> TRVItems
{
get { return _TRVItems; }
set { _TRVItems = value; OnPropertyChanged(nameof(TRVItems)); }
}
}
And the parent item class:
class TreeViewParentItem : INotifyPropertyChanged
{
public TreeViewParentItem(string name)
{
_Name = name;
TreeViewChildrenItems = new ObservableCollection<TreeViewChildItem>()
{
new TreeViewChildItem("first child"),
new TreeViewChildItem("second child")
};
}
// this is a name for the parent item - shall be displayed as a header and be editable
string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; OnPropertyChanged(nameof(Name)); }
}
private ObservableCollection<TreeViewChildItem> _TreeViewChildrenItems;
public ObservableCollection<TreeViewChildItem> TreeViewChildrenItems
{
get { return _TreeViewChildrenItems; }
set { _TreeViewChildrenItems = value; OnPropertyChanged(nameof(TreeViewChildrenItems)); }
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I can for the life of me not figure out why it is not displaying the names... Any ideas?
templates for certain DataType can be matches with objects of that type only if x:Key
is not set.
so remove x:Key="trvParents"
and x:Key="trvChildren"