我阅读了几个MVVM教程(1,2,3,4),但我无法找到问题的正确答案。
我的模型是这样的分层树:
public class MyModel {
public string Name { get; set; }
public Guid Id { get; set; }
public List<MyModel> Children { get; set; }
}
现在我想在这样的TreeView中显示它(如果来自MyModel类型的每个条目):
Root
|-SubElement
|-SubElement2
| |-SubSubElement1
|-SubElement3
现在我的问题:
INotifyPropertyChanged
,INotifyCollectionChanged
或者儿童列表是否属于ObservableCollection<MyModel>
类型?如果是,何时致电OnPropertyChanged()
?现在显示:
我想在TreeView中显示对象的名称,但是在选择元素时,我希望收到该事件的通知(并获取相应的元素)。 ViewModel必须以某种方式支持这一点。类似于持有我可以在XAML中绑定的列表(例如MyModelList
),例如:
<TreeView ...
ItemsSource="{Binding ElementName=MyModelList, Path=SelectedItem.Name}"
... >
我可以使用InputBindings
或EventTriggers
。
答案 0 :(得分:3)
尝试使用分层数据模板在TreeView中显示树结构
<Grid>
<Grid.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Children}"
DataType="{x:Type local:MyModel}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</Grid .Resources>
<TreeView ItemsSource="{Binding MyModelList}"/>
</Grid>
通过此MSDN博客以更好地理解 - TreeView and HierarchicalDataTemplate, Step-by-Step
答案 1 :(得分:1)
How would the corresponding View-Model look like?
在这种情况下,Model
和集合将在ViewModel
中。
Should the Model or the View-Model or both implement INotifyPropertyChanged
我建议您使用ObservableCollection<T>
,因为Collection中的所有更改都会自动(添加,删除等)出现在其中。将在Model
中的属性必须实现INotifyPropertyChanged
接口。我个人在Model
方面这样做,但是有这个想法的反对者,所以在哪里实施它 - 你个人的愿望。
这个想法的例子:
<强> Model
强>
public class MyModel : NotificationObject // he implement INotifyPropertyChanged
{
...
}
<强> ViewModel
强>
public ObservableCollection<MyModel> MyObjects
{
get;
set;
}
// in Constructor of ViewModel
MyLogObjects = new ObservableCollection<MyModel>();
When selecting the element, I want to be notified of that event
在WPF和Silverlight中TreeView.SelectedItem
是一个只读属性。在这种情况下,您可以看到this
示例:
<StackPanel x:Name="LayoutRoot">
<StackPanel.Resources>
<sdk:HierarchicalDataTemplate x:Key="ChildTemplate" ItemsSource="{Binding Path=Children}" >
<TextBlock Text="{Binding Path=Name}" />
</sdk:HierarchicalDataTemplate>
<sdk:HierarchicalDataTemplate x:Key="NameTemplate"
ItemsSource="{Binding Path=Children}"
ItemTemplate="{StaticResource ChildTemplate}">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
</sdk:HierarchicalDataTemplate>
</StackPanel.Resources>
<sdk:TreeView x:Name="myTreeView"
Width="400"
Height="300"
ItemsSource="{Binding HierarchicalAreas}"
ItemTemplate="{StaticResource NameTemplate}"
local:Attached.TreeViewSelectedItem="{Binding SelectedArea, Mode=TwoWay}" />
</StackPanel>
Silverlight
所需的前缀sdk:
对于通知事件,您可以在构造函数中为PropertyChangedEventHandler
创建ViewModel
事件处理程序,以便知道 SelectedItem
已更改:
public MyViewModel()
{
MyModel = new MyModel();
MyModel.PropertyChanged += new PropertyChangedEventHandler(MyModel_PropertyChanged);
}
private void MyModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName.Equals("SelectedItem"))
{
System.Diagnostics.Debug.WriteLine("SelectedItem changed");
}
}