我喜欢这样想:
正如您所说,观点是愚蠢的。在MVVM上具有开创性且经常相互联系的MSDN文章的作者约什·史密斯(Josh Smith)说,视图是“数据所穿的衣服”。视图从不实际包含或直接处理数据,它们仅绑定到视图模型的属性和命令。
模型是在业务对象中为应用程序域建模的对象。您的应用程序是音乐商店吗?也许您的模型对象将是艺术家,专辑和歌曲。您的应用程序是组织结构图浏览器吗?也许您的模型对象将是经理和员工。这些模型对象与任何形式的视觉渲染都不相关,它们甚至与您要放入其中的应用程序也没有直接关系-模型对象作为代表某种类型的对象家族应该完全有意义域。模型层通常还包括诸如服务访问器之类的东西。
这将我们带到Viewmodels。这些是什么?它们是为GUI应用程序建模的对象,表示它们提供了视图可使用的数据和功能。它们定义了正在构建的实际应用程序的结构和行为。对于模型对象,域是您选择的任何域(音乐商店,组织结构图浏览器等),但是对于viewmodel,域是图形应用程序。您的视图模型将封装应用程序所做的所有行为和数据。它们将对象和列表作为属性公开,以及诸如Commands之类的东西。命令只是包装在携带该对象的对象中的一种行为(最简单的方法调用)-这个想法很重要,因为视图是由数据绑定驱动的,该绑定将视觉控件附加到对象上。在MVVM中,您不会为按钮提供Click处理程序方法,
对我来说,最令人困惑的地方如下:
- 即使视图模型是图形应用程序的模型,它们也不直接引用或使用视觉概念。例如,您不希望在ViewModels中引用Windows控件-这些东西都放在视图中。ViewModel只是向控件或将绑定到它们的其他对象公开数据和行为。例如-您是否有一个带有ListBox的视图?您的视图模型几乎肯定会包含其中的某种集合。您的视图有按钮吗?您的视图模型几乎肯定会包含一些命令。
- 有几种对象可以视为“视图模型”。最简单的一种视图模型是直接以1:1关系表示控件或屏幕的视图模型,例如“屏幕XYZ具有一个文本框,一个列表框和三个按钮,因此,视图模型需要一个字符串,一个集合,和三个命令。” 适合视图模型层的另一种对象是模型对象的包装,该模型对象赋予其行为并使其在视图中更有用-在这里,您可以了解“厚”和“薄”视图模型层的概念。“薄”视图模型层是一组视图模型,这些模型将模型对象直接暴露给视图,这意味着视图最终直接绑定到模型对象的属性。这可以用于简单的只读视图,但是,如果您想让每个对象都有行为,该怎么办?您不希望在模型中使用该模型,因为该模型与应用程序无关,而仅与您的域相关。您可以将其放在包装模型对象的对象中,并提供更易于绑定的数据和行为。这个包装对象也被认为是一个视图模型,使它们成为一个“较厚”的视图模型层,在该层中,视图永远不会直接绑定到模型类上的任何内容。集合将包含包装模型的视图模型,而不仅仅是包含模型本身。您可以将其放在包装模型对象的对象中,并提供更易于绑定的数据和行为。这个包装对象也被认为是一个视图模型,使它们成为一个“较厚”的视图模型层,在该层中,视图永远不会直接绑定到模型类上的任何内容。集合将包含包装模型的视图模型,而不仅仅是包含模型本身。您可以将其放在包装模型对象的对象中,并提供更易于绑定的数据和行为。这个包装对象也被认为是一个视图模型,使它们成为一个“较厚”的视图模型层,在该层中,视图永远不会直接绑定到模型类上的任何内容。集合将包含包装模型的视图模型,而不仅仅是包含模型本身。
难题变得更深了-有很多习惯用法可以使ValueVM保持正常运行,例如ValueConverters,而当您开始考虑诸如可混合性,测试以及如何在应用程序中传递数据并确保每个视图模型都可以访问所需的行为(这是依赖注入的来源),但希望以上内容是一个好的开始。关键是将您的视觉效果,您的领域以及实际应用程序的结构和行为视为三件不同的事情。