我目前在 EF 中有三个模型(House、Room、Item)。
public class House
{
property int ID { get; set; }
property string Name { get; set; }
property List<Room> Rooms { get; set; }
}
public class Room
{
property int ID { get; set; }
property string Name { get; set; }
property List<Item> Items { get; set; }
}
public class Item
{
property int ID { get; set; }
property string Name { get; set; }
}
在我的 UI 中,我有一个 Treeview 和一个显示区域,当我双击 treeview 中的项目时,可以显示项目的更多详细信息以进行修改。
为了提高性能,我的 TreeView 调用了一个返回以下 DTO/s 的网络服务
public class LayoutItemDTO
{
property int ID { get; set; }
property string Name { get; set; }
property List<LayoutItemDTO> Children { get; set; }
}
这些 DTO 是使用对房屋、房间、元素模型的数据库查询构建的。
现在,当用户双击 TreeView 上的房屋项目时,它会调用网络服务将带有房间集合的房屋模型返回到 View 中,供用户添加/删除房间,当他们关闭 View 时,它会提示保存.
当用户双击房间(即向房间添加/删除项目)时,也会发生同样的情况。
除了保持 TreeView 和打开的 View 同步之外,这一切都很好用,所以如果他们更改房间的名称或添加/删除一个项目,我希望它反射(reflect)在内存中的 TreeView 中,并在他们取消更改时恢复关闭。
目前我已经使用事件聚合器完成了这项工作,但为每个操作调用事件似乎不整洁,如果我可以只使用 WPF 绑定(bind),它会立即工作。
不在 TreeView 上使用相同模型的原因是这些模型的信息比显示的多得多,当获取所有信息时会导致性能问题。
最佳答案
数据绑定(bind)和 INotifyPropertyChanged
如果您希望使用数据绑定(bind)将对象的更改反射(reflect)在 UI 中,则必须实现 INotifyPropertyChanged
模型类中的接口(interface)(如果您使用 MVVM 模式,则在 ViewModel 中)。
通过实现接口(interface),每次修改属性值时都会触发一个事件 ( PropertyChanged
),数据绑定(bind)到该属性的控件将刷新以显示新值。
您可以在这里找到示例:How to: Implement the INotifyPropertyChanged Interface
收藏
对于集合,如果集合实现 INotifyCollectionChanged
,WPF 数据绑定(bind)将起作用。 . List<T>
类型不实现此接口(interface),因此 TreeView 不会反射(reflect)列表中的添加/删除。类型ObservableCollection<T>
实现了这个接口(interface),所以你只需要改变List<LayoutItemDTO>
至 ObservableCollection<LayoutItemDTO>
并且应该反射(reflect)更改。
MVVM
正如您提到的使用 MVVM,我想补充一点,我通常会有 ObservableCollection
和 INotifyPropertyChanged
我的 ViewModel 中的实现。您可能想要创建一个 LayoutItemViewModel
这将封装一个 LayoutItemDTO
.
我还可以建议您查看现有的工具包和框架,它们对为 MVVM 实现“管道代码”有很大帮助(例如 INotifyPropertyChanged
实现)。我主要使用 MVVM Light,但根据您的需要还有很多其他可用的。
这里还有一个以 MVVM 方式实现 TreeView 数据绑定(bind)的好链接:Simplifying the WPF TreeView by Using the ViewModel Pattern
关于c# - 具有不同 DTO 的 View 模型之间的 MVVM 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26504363/