Wpf MVVM和VM集合
一个普通的senario:一个包含项目模型集合的模型。Wpf MVVM和VM集合,wpf,mvvm,collections,viewmodel,Wpf,Mvvm,Collections,Viewmodel,一个普通的senario:一个包含项目模型集合的模型。 有一群人的房子 如何为MVVM正确构建此结构-特别是在使用添加和删除更新模型和ViewModel集合方面? 模型房屋包含模型人员的集合(通常是一个列表)。 视图模型HouseVM包含它包装的房屋对象和视图模型PeopleVM(observedcollection)的observedcollection。注意,我们在这里结束时,HouseVM包含两个集合(需要同步): 1. HouseVM.House.List 2. 室内虚拟机可观察采集 当
有一群人的房子 如何为MVVM正确构建此结构-特别是在使用添加和删除更新模型和ViewModel集合方面? 模型
房屋
包含模型人员的集合
(通常是一个列表
)。视图模型
HouseVM
包含它包装的房屋对象和视图模型PeopleVM
(observedcollection
)的observedcollection。注意,我们在这里结束时,HouseVM包含两个集合(需要同步):1. <代码>HouseVM.House.List
2. <代码>室内虚拟机可观察采集 当房屋更新为新人员(添加)或人员离开(删除)时,现在必须在两个集合中处理该事件:模型房屋人员集合和VM房屋VM人员VM ObservableCollection 此结构是否正确MVVM?
还有什么方法可以避免对添加和删除进行双重更新吗?在这种情况下,我只需让模型暴露
可观察的收集
s,而不是列表
s。没有特别的理由不应该这样做。ObservableCollection
位于System
程序集的System.Collections.ObjectModel
命名空间中,因此不存在不合理的额外依赖项,您几乎肯定有System
<代码>列表位于mscorlib
中,但这和任何东西一样都是一件历史文物
这大大简化了模型-视图-模型的交互,我看不出不这样做的理由,在模型上使用List
s只会产生很多令人不快的锅炉板代码。毕竟,你对这些事件很感兴趣
另外,为什么您的HouseVM
要包装observedcollection
,而不是observedcollection
?VM用于绑定到视图,因此我认为绑定到您的ObservableCollection
的任何东西实际上都对人感兴趣,否则您是在绑定中绑定的,或者这有用的具体原因是什么?我一般不会让一个虚拟机暴露其他虚拟机,但也许那只是我
编辑关于库/WCF
我不明白为什么库中有一个模型,或者甚至由WCF服务器公开会影响它们是否引发事件,这对我来说似乎完全有效(显然WCF服务不会直接公开事件)。如果您不喜欢这样,我认为您必须链接多个更新,尽管我想知道您是否只是在手动执行与ObservableCollection
中的事件相同的工作,除非我误解了其中一些内容
就我个人而言,就像我说的,我会让虚拟机保持简单,让它们暴露最小值,而不暴露其他虚拟机。它可能需要一些重新设计,使某些部分有点痛苦(例如,Converter
s,但是,您最终会得到一个简单、易于管理的设计,并在边缘处理一些简单的刺激
在我看来,你目前的路线很快就会变得非常复杂,最重要的是,很难遵循……然而,YMMV,这只是我的经验:)
也许将一些逻辑转移到显式服务可能会有所帮助?您的一般方法非常适合MVVM,让一个ViewModel公开一组其他ViewModel是一个非常常见的场景,我到处都在使用它。我不建议像Nicodems13所说的那样直接在ViewModel中公开项目,因为最终您的视图绑定到模型,而集合的项目之间没有ViewModels。所以,第一个问题的答案是:是的,这是有效的MVVM
在第二个问题中,您要解决的问题是房屋模型中的人员模型列表与房屋视图模型中的人员视图模型列表之间的同步。您必须手动执行此操作。所以,没有办法避免这种情况
您可以做的事情:实现一个定制的observateCollection
,ViewModelCollection
,将其更改推送到基础集合。要获得双向同步,请将模型的集合也设置为ObservableCollection,并注册到ViewModelCollection中的CollectionChanged
事件
这是我的实现。它使用ViewModelFactory服务等,但只需看看一般原理。我希望它能帮助
//
///可观察的ViewModels集合,将更改推送到相关的模型集合
///
///集合中ViewModels的类型
///基础集合中的模型类型
公共类VmCollection:ObservableCollection
其中TViewModel:类,IViewModel
其中TModel:class
{
私有只读对象_上下文;
私有只读ICollection_模型;
私人楼宇同步禁用;
私有只读IViewModelProvider\u viewModelProvider;
///
///建造师
///
///要同步的模型列表
///
///
///
///确定是否应删除ViewModels集合
///在构造时从模型集合中获取
///
公共VmCollection(ICollection模型,IViewModelProvider viewModelProvider,对象上下文=null,bool autoFetch=true)
{
_模型=模型;
_上下文=上下文;
_viewModelProvider=viewModelProvider;
//同步的寄存器更改处理
//从视图模型到模型
CollectionChanged+=ViewModelCollectionChanged;
//如果模型集合是可观察的,则寄存器更改
//处理从模型到ViewModels的同步
如果(模型是可观察的集合)
{
var observableModels=可观测模型