我试图在MVVM
应用中使用WPF
构建TreeView,但我不了解如何处理HierarchicalDataTemplate
。我的TreeView
应该代表一个文件夹结构,其中包含文件夹中的文件夹等等。
我的文件夹ViewModel
定义如下:
public class TreeViewFolderViewModel : ViewModelBase
{
private int _id;
private int _parentId;
private string _text;
private string _key;
private ObservableCollection<TreeViewFolderViewModel> _children;
public int Id
{
get { return this._id; }
set { Set(() => Id, ref this._id, value); }
}
public int ParentId
{
get { return this._parentId; }
set { Set(() => ParentId, ref this._parentId, value); }
}
public string Text
{
get { return this._text; }
set { Set(() => Text, ref this._text, value); }
}
public string Key
{
get { return this._key; }
set { Set(() => Key, ref this._key, value); }
}
public ObservableCollection<TreeViewFolderViewModel> Children
{
get { return this._children ?? (this._children =
new ObservableCollection<TreeViewFolderViewModel>()); }
set { Set(() => Children, ref this._children, value); }
}
}
我的模型与我的ViewModel
具有相同的结构,因此最终的ViewModel
是包含子文件夹的文件夹列表,依此类推。我使用递归加载所有这些文件夹,那部分工作正常。
我遇到的问题是如何定义ViewModel并将其加载到实际的TreeView中。
我已经阅读了socket.io,而我或多或少地了解了正在发生的事情,但TreeView
的每个级别代表了不同的对象类型,而我的{{{} 1}}只有一种对象类型,我对如何定义它感到困惑。
我的MainWindowViewModel中的根TreeView
属性是ViewModel
类型,这意味着我有一个对象代表我的TreeView的根。此对象具有TreeViewFolderViewModel
类型的子级,而这些子级又具有TreeViewFolderViewModel
类型的子级,等等
我如何在TreeViewFolderViewModel
中定义此内容?我有以下定义:
XAML
我的<TreeView Grid.Row="1" Margin="5,0,5,5" ItemsSource="{Binding RootFolder}"/>
模板定义如下:
Hierarchical
但是没有任何东西在加载。
关于我如何解决这个问题的任何想法?
感谢。
答案 0 :(得分:1)
我准备了一个小样本来说明。
<强>的ViewModels 强>
public class TreeViewFolderViewModel : ViewModelBase
{
private int id;
public int Id
{
get { return id; }
set { id = value; OnPropertyChanged("Id"); }
}
private string text;
public string Text
{
get { return text; }
set { text = value; OnPropertyChanged("Text"); }
}
private ObservableCollection<TreeViewFolderViewModel> children;
public ObservableCollection<TreeViewFolderViewModel> Children
{
get
{
return children ?? (children =
new ObservableCollection<TreeViewFolderViewModel>());
}
set { children = value; OnPropertyChanged("Children"); }
}
}
public class TreeViewModel : ViewModelBase
{
private List<TreeViewFolderViewModel> items;
public List<TreeViewFolderViewModel> Items
{
get { return items; }
set { items = value; OnPropertyChanged("Items"); }
}
public TreeViewModel()
{
Items = new List<TreeViewFolderViewModel>()
{
new TreeViewFolderViewModel()
{
Id =0, Text="RootFolder", Children=new ObservableCollection<TreeViewFolderViewModel>()
{
new TreeViewFolderViewModel() { Id = 10, Text = "FirstFolder", Children=new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 11, Text = "FirstChild" } } } ,
new TreeViewFolderViewModel() { Id = 20, Text = "SecondFolder", Children = new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 21, Text = "SecondChild" } } } ,
new TreeViewFolderViewModel() { Id = 30, Text = "ThirdFolder", Children = new ObservableCollection<TreeViewFolderViewModel>() { new TreeViewFolderViewModel() { Id = 31, Text = "ThirdChild" } } }
}
}
};
}
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
<强> MainWindow.xaml 强>
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:TreeViewModel />
</Window.DataContext>
<Window.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Children}"
DataType="{x:Type local:TreeViewFolderViewModel}">
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Id" />
<Binding Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView ItemsSource="{Binding Items}" />
</Grid>
</Window>