В проекте WPF я создал Treeview, который должен отображать элементы из ObservableCollection и только одного поколения дочерних элементов. Однако Treeview показывает только родительские объекты, но не даже их имена, не говоря уже о дочерних объектах. Он просто показывает «WpfTreeViewInPlaceEdit.MVVM.Model.TreeViewParentItem».
Вот мой 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>
Соответствующая 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)); }
}
}
И класс родительского элемента:
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));
}
}
Я хоть убей не могу понять, почему имена не отображаются... Есть идеи?





шаблоны для определенного типа данных могут сопоставляться с объектами этого типа, только если x:Key не установлен.
поэтому уберите x:Key = "trvParents" и x:Key = "trvChildren"
О, мои дни, спасибо. Я редактировал и экспериментировал с кодом (который я скопировал с другого веб-сайта), и в какой-то момент я изменил его так, что Visual Studio сказала, что моему элементу нужен ключ. С тех пор я просто оставил его там, хотя он был бесполезен.