我对MVVM模式中的View
和ViewModel
有清晰的认识。我打算在我的应用程序中实现MVVM模式。我正面临着关于模型的问题。我有.xml文件,它被解析,信息显示在视图中。
我需要第一次收到有关模型更改的通知。从需求开始,我需要得到通知。
那么如何实施该模型?
我是否应该在模型类中实现INotifyPropertyChanged
接口? (我读过该模型不应该实现INotifyPropertyChanged
接口,因为它是WPF特定的)
答案 0 :(得分:46)
在模型中实现INotifyPropertyChanged
是完全可以接受的 -
通常,该模型实现了易于使用的设施 绑定到视图。这通常意味着它支持属性和 集合通过
INotifyPropertyChanged
更改了通知INotifyCollectionChanged
接口。表示的模型类 对象集合通常来自ObservableCollection<T>
类,它提供了一个实现INotifyCollectionChanged
界面。
虽然由您来决定是否需要这种类型的实现,但请记住 -
如果您的模型类没有实现所需的接口怎么办?
有时您需要处理没有的模型对象 实施
INotifyPropertyChanged
,INotifyCollectionChanged
,IDataErrorInfo
或INotifyDataErrorInfo
个接口。在那些情况下, 视图模型可能需要包装模型对象并公开 视图所需的属性。这些属性的值将 由模型对象直接提供。视图模型将 为它公开的属性实现所需的接口 视图可以轻松地将数据绑定到它们。
取自 - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
我曾在一些项目中工作,我们的模型中没有实现INotifyPropertyChanged
,因此我们遇到了很多问题;在VM中需要不必要的属性重复,同时我们必须在将它们传递给BL / DL之前更新底层对象(使用更新的值)。
如果您需要处理模型对象的集合(比如在可编辑的网格或列表中)或复杂模型,您将特别遇到问题;模型对象不会自动更新,您必须管理VM中的所有内容。
答案 1 :(得分:15)
标准MVVM方法仅在ViewModel上实现INotifyPropertyChanged
。目的是在ViewModel中发生更改时刷新View上的相应绑定。
但是,这会定位视图对ViewModel 的更改。也就是说,当您更改TextBox
中的值时,ViewModel上的INotifyPropertyChanged
实现将刷新相关的绑定,以便View正确更新。
不涵盖外部源(如数据库更改或其他界面)对模型所做的更改。只要所有数据修改都来自View,ViewModel应该知道所有更改并知道要更新的内容。例如,如果您知道模型中更改变量Foo
也会更改模型上Bar
的值,那么同时调用OnPropertyChanged(Foo)
和OnPropertyChanged(Bar)
是明智之举更改Foo
的值时,在ViewModel中。
另一种方法是使用Model和ViewModel之间的事件来刷新ViewModel上需要更新的那些值。如果,正如您所说的那样,通知是“仅限第一次”,那么在某些触发器上执行手动一次性刷新也应该有效。
答案 2 :(得分:10)
这是使用MVVM时非常常见的问题,INotifyPropertyChanged
不是WPF特定的,因为它是System.ComponentModel
的一部分,因此无需在解决方案中添加任何WPF特定引用。
如果要在模型中实现INofityPropertyChanged
,它可以在ViewModel(代理属性)中保存更多代码。因此,您的模型可以使用INotifyPropertyChanged
。
答案 3 :(得分:9)
有时可以让模型实现INotifyPropertyChanged
接口。
例如,如果模型具有许多要显示的属性,并且您希望避免在viewmodel中实现大量代码(代理属性)以公开此类模型属性。
答案 4 :(得分:3)
我不确定你的意思。在VM中,您可能具有INotifyPropertyChanged
或DependencyProperty-es(在这种情况下,VM必须从DependencyObject
派生)。两者都没有意义。没有它们也没有意义。
在模型中,你可以做任何你想做的事。发射/接收事件的能力很好,但并不总是可以依赖它们。基本上,模型取决于源数据和相关的东西,而viewmodel具有模型与表示层的接口负载。由于WPF处理事件,至少 VM必须提供一些通知机制。
答案 5 :(得分:3)
这是“纯粹的”MVVM程序员和其他人之间的经典论据。
我倾向于随时随地阅读书籍,因为大部分时间都是有意义的。但是,在某些情况下,根据需要即兴创建代码会减少大量重复代码。
在您的情况下,您可以将XML读取到模型类,并将模型类的副本复制到viewmodel,或者将所需的属性从模型复制到视图模型。这样您就可以控制更新UI /模型。如果您遵循第一种方法,则需要在模型类中实现Inotifypropertychanged,这是可以接受的。
话虽如此,我会尽量遵循第二种方法,因为这样可以让我精确控制视图中显示/操作的所有属性。另外,我会感觉好多了,我没有打破MVVM模式。