在涉及列表/集合时,我无法理解如何应用MVVM模式。
假设MainModel
有一些属性和方法,以及包含其他DetailModel
个对象的列表。可以添加,删除或重新排序DetailModel
个对象。
MainView
将显示与根模型相关的一些控件,并从列表中填充ListBox
。每个项目都会通过DetailModelView
UserControl
拥有自己的子视图。
最后,有一个MainViewModel
。这个属性由MainModel
的属性和方法支持,绑定到主视图,更改通知保持所有内容同步。 (到目前为止,我对这种模式感到满意 - 如果有一些我缺少的基本内容,请更多说明这一点......)
在处理清单时,我感到困惑。我遇到过几个示例,其中MainViewModel
只是将DetailModels
的列表公开给视图,而DetailModelViews
直接绑定到模型。这个功能,但是有问题。它并不一贯遵循模式(没有DetailViewModel
存在),它促使我在我的细节模型中包含一些与UI相关的代码。我似乎很清楚,MainViewModel
应该为要绑定的UI公开DetailViewModels
列表,但我仍然坚持如何实现这样的事情!
如何管理两个列表(DetailModels
和DetailViewModels
)?我真的很困惑,因为我最初填充DetailViewModel
列表,以及我应该如何处理添加,删除或更改项目的顺序以保持它们同步!
答案 0 :(得分:12)
通常Models
只不过是数据对象。它们不应包含任何代码来执行添加/删除列表中的项目等操作。这是ViewModel's
工作。
在您的情况下,我会创建一个具有以下属性的MainViewModel
:
ObservableCollection<DetailViewModel> Details
ICommand AddDetailCommand
ICommand RemoveDetailCommand
如果您的MainModel
类是数据对象,您可以公开它,也可以从MainViewModel
公开它的属性。公开它的属性是“MVVM纯粹主义”方法,而暴露整个模型有时更实用。
您的MainViewModel
负责创建DetailViewModels
的初始列表,并负责添加/删除这些项目。例如,在PropertyChanged
属性的MainViewModel.MainModel
事件中,它可能会重建MainViewModel.Details
集合,而CollectionChanged
属性的MainViewModel.Details
事件将更新MainViewModel.MainModel.Details
{1}}
答案 1 :(得分:5)
您拥有单独的DetailModels
列表和DetailViewModels
列表是正确的。 DetailViewModels列表应该是ObservableCollection<DetailViewModel>
类型的属性。您可以在设置模型时填充可观察列表(如果将模型传递给ViewModel的构造函数,则可以在构造时填充。)
private ObservableCollection<DetailViewModel> m_details;
public IEnumerable<DetailViewModel> Details
{
get { return m_details; }
}
您可以订阅m_details。CollectionChanged。您可以在此处理模型中列表内容的重新排序。
我希望这会有所帮助。
答案 2 :(得分:2)
根据我的经验,你唯一一次将模型对象暴露给视图就是你做的是简单的只读呈现,例如:在ComboBox
中显示字符串属性。如果涉及对象的任何实际UI(特别是涉及双向数据绑定的UI),则需要视图模型。
通常,主VM的构造函数如下所示:
public MasterViewModel(MasterModel m)
{
_Model = m;
_Detail = new ObservableCollection<DetailViewModel>(m.Detail);
}
其中MasterModel.Detail
是DetailModel
个对象的集合,_Detail
是展示给视图的Detail
属性的支持字段。
就添加,删除和重新排序此列表中的项目而言,在UI中至少这将通过MasterViewModel
上的命令完成,这些命令必须同时操作MasterModel.Detail
和{{ 1}}。这有点痛苦,但除非您想在每次更改MasterViewModel.Detail
后重新填充MasterViewModel.Detail
,否则这是不可避免的。
另一方面,如果你一直想知道“为什么我需要为视图模型编写单元测试?”,现在你知道了。
答案 3 :(得分:1)
我认为这是一个答案,我认为使用ObservableViewModelCollection<TViewModel, TModel>
这很好,懒惰。它需要在ctor中使用ObservableCollection和ViewModelFactory。我喜欢它,因为它将状态保持在它所属的模型层。 GUI上的用户操作可以调用VM上的命令,该命令通过M上的公共方法操纵M.M层上的任何结果更改将由此链接中的类自动处理。
https://stackoverflow.com/q/2177659/456490
请注意我对SL与WPF的评论