我正在使用带有Prism和Silverlight的MVVM。我有一个模型的多个不同视图。当我写更多视图时,他们的ViewModel似乎复制了许多与处理这个模型相关的常见代码。我没有在所有虚拟机中重复相同的公共代码,而是试图将其推回到模型中(这可能会引起太多关注)。或者可能进入一些常见的ViewModel基类?或者我的虚拟机可能需要它们和模型之间的第二级“共享虚拟机”?此单个共享实例,第二级VM将合并多个常规VM共享的行为和状态。
关于这些问题和可能的方法的任何评论?
感谢评论家伙。我可能应该告诉你更多有关特定“共享”VM代码的信息。
我可以看到将某些未来代码放在VM基类中,但我正在查看的特定“共享”代码似乎属于由实现的INotifyPropertyChanged模型本身。这部分基于此other thread。
我不认为这违反了SoC,因为该模型本质上是动态的。它的某些属性仅在特定时间有效。模型的动态性质不仅仅是对UI很重要的东西,适当的单元测试也会关心它。因此,这个模型似乎需要一个INotifyPropertyChanged。
对此有何评论?
答案 0 :(得分:1)
如果公共代码可以由所有 ViewModel共享,那么值得将它放入基本的ViewModel类型中。
如果公共代码仅由与特定模型交互的ViewModel共享,则可以使用“共享”ViewModel。
答案 1 :(得分:0)
我已成功使用New York Times Silverlight Kit中的ViewModel继承来减少复制代码。请查看CommunityRecentComments及其父类CommunityBase以获取示例。
答案 2 :(得分:0)
各种MVVM框架中的大多数“基本ViewModel”类往往包含对INotifyPropertyChanged的支持,并且通常支持调度回UI线程。
除此之外,我认为如果你有许多ViewModel共享应该进入基类的功能,我使用这个模式越多,我发现自己使用ViewModels的一个相当浅的层次结构,一个代码的基本ViewModel所有视图模型都通用,并且通常是另一个基类,用于UI区域中的常见功能。通常是常用命令或UI共享元素的位置。
ViewModelBase - > ProductsViewModelBase - > NewProductViewModel
答案 3 :(得分:0)
在完全是MVVM的SoapBox Core中,我定义了一个IViewModel接口和一个AbstractViewModel基类,正如Nigel所说,它只是实现了INotifyPropertyChanged。 (请注意,SoapBox Core是WPF,而不是Silverlight,但在这种情况下它并不是什么大问题。我也做过类似的Silverlight工作。)
然后我定义了更多从IViewModel继承的接口(如IMenuItem)和更抽象的类,它们提供了这些接口的基本实现。
现在,它占了整个ViewModel树,但正如你所说,还有Model树。我现在花了将近一年的时间与MVVM合作,这是我的大悟:不要写一个模型。如果您是从头开始构建应用程序,只需将所有内容放在ViewModel中,否则最终会复制大量代码。
我唯一困扰拥有模型的情况是我使用的第三方库没有实现INotifyPropertyChanged,因此不容易被绑定。我相信实体框架的自动生成代码也可能在这里,但我注意到一些实体框架现在允许您在实体本身中实现INotifyPropertyChanged。
说真的,我们应该将它重命名为ViewModel模式并完成它。 :)