假设我有一个模型,它公开了一组对象,我将在GUI中显示和更改。
所以我们有Model公开了一个ModelItem的集合。
View绑定到一个ViewModel,它暴露了ViewModelItem的ObservableCollection。 ViewModelItem是ModelItem的Viewmodel
View包含ListBox和DataTemplate。 DataTemplate用于ViewModelItem类型的项目。 View DataContext指向ViewModel的一个实例。 ListBox绑定到ObservableCollection。
我控制所有代码。
到目前为止这么简单。问题:
将模型上的集合公开为ObservableCollection是否可以接受?此外,在Model和ModelItem上实现INotifyPropertyChanged是否可以接受?
我担心的是我混淆了模型和视图模型之间的分离,但是常识说,这是一种通知模型中元素更改的机制,让我们使用它......
只是想从别人那里获得一些观点。
由于
答案 0 :(得分:4)
简答: 是。需要通知更改时,请在模型上使用通知界面。不要担心这会弄乱你的代码。务实。
答案很长: 我的理念是这样的:当实现MVVM时,当没有额外的事情要做时,直接绑定到模型对象。当您需要新的东西(新行为,视图将使用的属性等)时,您将模型对象包装在ViewModel对象中。 ViewModel除了从模型委托数据外什么都不做,只不过是额外的代码。当您需要对模型对象提供的数据执行某些操作时,您将引入该层。
因此,为了进一步扩展我的想法,(以及更直接地回答你的问题),模型需要有一种方法在事情发生变化时告诉ViewModel。通常,模型数据是不可变的,因此它不需要这种通知机制,因此没有必要。但是,通常情况下模型也会发生变化。发生这种情况时,模型有两个选项:使用自定义通知方法(事件,委托等)或使用INotifyPropertyChanged
。
如果查看INotifyPropertyChanged
的命名空间,它位于System.ComponentModel
- 而不是视图 - 所以我更喜欢在模型中使用它。它是一个众所周知的界面,您可以使用它从您的视图直接绑定到您的模型。不需要实现任何不同的东西。
进一步采用这一理念,ObservableCollection
位于System.Collections.ObjectModel
- 也不是特定于视图的 - 并且它实现了System.Collections.Specialized.INotifyCollectionChanged
,它也不是特定于视图的。换句话说,ObservableCollection
被设计为一个集合,通知观察者变化。如果您的模型需要这样做,那么ObservableCollection
就是您的工具。尽管WPF和Silverlight使用这些接口进行数据绑定,但恰好很方便(不是偶然)。
我想这是一种冗长的说法:“是的。当您需要通知更改时,请在您的模型上使用您的通知界面。不要担心这会使您的代码变得混乱。务实。”
答案 1 :(得分:3)
没有。这太糟糕了。您的模型不应该知道它是如何使用的。赋予它这些知识会击败MVVM的对象 该模型永远不会知道它被WPF,winforms,dos控制台,服务或lib使用。如果你告诉它,你就错了。 它也应该是独立于框架的,如果它是MVVM,MVC或MXXX的一部分,那就不用了!
答案 2 :(得分:2)
两者都可以接受。我甚至会说必需来做两件事。你的常识能力很好。 :)
我只想补充一点,如果你不需要ModelItem
的所有MVVM功能,那么你可以通过公开ObservableCollection<ModelItem>
而不是ObservableCollection<ViewModelItem>
来削减一些角落,并修改你的DataTemplate
以适应。这将为您节省相当多的“准备”代码,因此权衡利弊。
答案 3 :(得分:2)
如果数据模型需要更改通知,则在数据模型中使用更改通知当然是可以接受的。仅仅因为UI需要更改通知而在数据模型中使用更改通知也是有问题的。
通常,我将数据模型设计为好像 没有UI,并将视图模型用作从UI隐藏数据模型的实现细节的抽象层。另一方面,在动态应用程序中,可能会出现对变更通知的需求非常普遍,以至于将其放入数据模型更有意义。