简体   繁体   English

具有不同DTO的视图模型之间的MVVM通信

[英]MVVM communication between viewmodels with different DTO's

I currently have three models in EF (House,Room,Item). 我目前在EF中有三个模型(房屋,房间,物品)。

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; }
}

In my UI I have a Treeview and a display area to show the items further details for modification when I double click an item in the treeview. 在我的UI中,我有一个Treeview和一个显示区域,用于在双击Treeview中的项目时显示这些项目的更多详细信息。

My treeview to improve performance calls a webservice which returns the following DTO/s 为了提高性能,我的Treeview调用了一个Web服务,该服务返回以下DTO /秒

public class LayoutItemDTO
{
   property int ID { get; set; }
   property string Name { get; set; }
   property List<LayoutItemDTO> Children { get; set; }
}

these DTO's are mapped built using a query to the database on the house, room, item models. 这些DTO通过使用查询映射到房屋,房间,物品模型的数据库。

Now when the user double clicks a house item on the treeview it calls a webservice to return the house model with the rooms collection into a view for the user to add/remove rooms and when they close the view it prompts for a save. 现在,当用户双击树视图上的房屋项目时,它将调用一个Web服务,将带有Rooms集合的房屋模型返回到视图中,以供用户添加/删除房间,并在他们关闭视图时提示进行保存。

The same happens when the user double clicks on a room (ie add/remove items to a room). 当用户双击房间时(即向房间添加/删除项目),也会发生同样的情况。

This all works great apart from keeping the treeview and the opened view in sync so if they change the name of a room or add/remove an item I want it reflecting in the treeview in memory and reverting if they cancel the changes on close. 除了保持树视图和打开的视图同步之外,所有这些都很好用,因此,如果它们更改房间的名称或添加/删除我希望它反映在内存中的树视图中的项目,以及如果它们在关闭时取消更改,则恢复原样。

Currently I have done this using the event aggregator but it seems untidy calling events for each action, if I could just use WPF binding it would all work instantly. 目前,我已经使用事件聚合器完成了此操作,但似乎每个动作调用事件都很麻烦,如果我可以仅使用WPF绑定,那么所有操作都会立即生效。

The reason for not using the same models on the treeview is due to these models having a lot more information on them than is shown, when obtaining everything this causes a performance problem. 在树状视图上不使用相同模型的原因是由于这些模型在显示的信息上比显示的信息多得多,因此在获取所有内容时会导致性能问题。

Databinding and INotifyPropertyChanged 数据绑定和INotifyPropertyChanged

If you want that changes on your objects to be reflected in the UI using data binding, you have to implement INotifyPropertyChanged interface in your model class (or in a ViewModel if you are using MVVM pattern). 如果希望使用数据绑定将对象的更改反映在UI中,则必须在模型类中(如果使用MVVM模式,则在ViewModel中)实现INotifyPropertyChanged接口。

By implementing the interface, an event ( PropertyChanged ) will be triggered each time a property value is modified, and the controls databinded to the property will refresh to show the new values. 通过实现该接口,每次修改属性值时都会触发一个事件( PropertyChanged ),并且绑定到该属性的控件的数据将刷新以显示新值。

You can find an example here: How to: Implement the INotifyPropertyChanged Interface 您可以在此处找到一个示例: 如何:实现INotifyPropertyChanged接口

Collections 集合

For the collection, WPF databinding will work if the collection implements INotifyCollectionChanged . 对于集合,如果集合实现INotifyCollectionChanged ,则WPF数据绑定将起作用。 The List<T> type does not implement this interface, so the TreeView won't reflect add/removes from the list. List<T>类型不实现此接口,因此TreeView不会反映列表中的添加/删除。 The type ObservableCollection<T> implements this interface, so you just have to change List<LayoutItemDTO> to ObservableCollection<LayoutItemDTO> and the changes should be reflected. 类型ObservableCollection<T>实现此接口,因此您只需将List<LayoutItemDTO>更改为ObservableCollection<LayoutItemDTO>并应反映更改。

MVVM MVVM

As you mentioned using MVVM, I would add that I normally would have ObservableCollection and INotifyPropertyChanged implementations in my ViewModels. 正如您提到的使用MVVM一样,我要补充一点,我通常在ViewModels中具有ObservableCollectionINotifyPropertyChanged实现。 You may want to create a LayoutItemViewModel that would encapsulate a LayoutItemDTO . 您可能希望创建一个LayoutItemViewModel ,将封装一个LayoutItemDTO

I can also advise you to have a look at existing toolkits and frameworks that can help a lot for implementing "plumbing code" for MVVM (like INotifyPropertyChanged implementation). 我还建议您看一下现有的工具箱和框架,这些工具箱和框架可以为实现MVVM的“管道代码”(例如INotifyPropertyChanged实现)提供很大帮助。 I use mainly MVVM Light, but there are a lot of other availabe depending on your needs. 我主要使用MVVM Light,但根据您的需求,还有很多其他可用的方法。

Here is also a good link for implementing TreeView databinding in a MVVM manner: Simplifying the WPF TreeView by Using the ViewModel Pattern 这也是以MVVM方式实现TreeView数据绑定的好链接: 通过使用ViewModel模式简化WPF TreeView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM