mvvm - MVVM 的基本概念——ViewModel 应该做什么?

标签 mvvm

试图掌握MVVM的概念,我已经阅读了几篇博客并查看了一些项目。

据我所知, View 是愚蠢的,它只知道如何呈现传递给它的东西。

模型只是普通的数据,而 ViewModel 就像是两者之间的填充物,它应该从 Model 获取信息并将其传递给 View,而 View 应该知道如何呈现它。或者反过来,如果 View 中的信息发生变化,它应该将更改传递给 Model。

但我仍然不知道如何应用这个概念。有人可以解释一个非常简单的场景,以便我掌握这个概念吗?我已经看过几个项目,但仍然没有完全理解,所以如果有人能用简单的英语写出来,那就太好了。

最佳答案

我喜欢这样想:

正如你所说,观点是愚蠢的。 Josh Smith 是 MVVM 上开创性的并且经常被链接的 MSDN article 的作者,他说 View 是“数据穿的衣服”。 View 从不实际包含数据或直接操作它,它们只是绑定(bind)到 View 模型的属性和命令。

模型是对应用程序域建模的对象,就像在业务对象中一样。您的应用程序是音乐商店吗?也许您的模型对象将是艺术家、专辑和歌曲。您的应用程序是组织结构图浏览器吗?也许您的模型对象将是经理和员工。这些模型对象与任何类型的视觉渲染无关,它们甚至与您将它们放入的应用程序没有直接关系 - 您的模型对象作为代表某种类型的对象家族应该完全有意义域的。模型层通常还包括诸如服务访问器之类的东西。

这将我们带到了 Viewmodels。这些是什么?它们是对 GUI 应用程序建模的对象,这意味着它们提供 View 使用的数据和功能。它们定义了您正在构建的实际应用程序的结构和行为。对于模型对象,域是您选择的任何域(音乐商店、组织结构图浏览器等),但对于 View 模型,域是图形应用程序。您的 View 模型将封装应用程序所做的一切的行为和数据。他们将对象和列表公开为属性,以及诸如命令之类的东西。命令只是一种行为(最简单的方法调用),它封装在一个携带它的对象中——这个想法很重要,因为 View 是由数据绑定(bind)驱动的,数据绑定(bind)将可视化控件附加到对象上。在 MVVM 中,您不会为按钮提供 Click 处理程序方法,而是将其绑定(bind)到一个命令对象(由 View 模型中的属性提供),该对象包含您单击时要运行的功能。

对我来说,最令人困惑的是以下几点:

  • 尽管 View 模型是图形应用程序的模型,但它们并不直接引用或使用视觉概念。例如,您不希望在您的 ViewModel 中引用 Windows 控件 - 这些东西会出现在 View 中。 ViewModel 只是将数据和行为暴露给将绑定(bind)到它们的控件或其他对象。例如 - 你有一个包含 ListBox 的 View 吗?您的 View 模型几乎肯定会在其中包含某种集合。你的 View 有按钮吗?您的 View 模型几乎肯定会在其中包含一些命令。
  • 有几种对象可以被视为“ View 模型”。最容易理解的 View 模型是一种以 1:1 关系直接表示控件或屏幕的 View 模型,如“屏幕 XYZ 有一个文本框、一个列表框和三个按钮,因此 View 模型需要一个字符串、一个集合、和三个命令。”适合 View 模型层的另一种对象是模型对象的包装器,它赋予它行为并使其对 View 更有用——这是您进入“厚”和“薄” View 模型层概念的地方。 “瘦” View 模型层是一组 View 模型,它们将模型对象直接暴露给 View ,这意味着 View 最终会直接绑定(bind)到模型对象上的属性。这可以用于简单的只读 View 之类的事情,但是如果您想要与每个对象相关联的行为怎么办?您不希望在模型中使用它,因为模型与应用程序无关,它只与您的域相关。您可以将它放在一个对象中,该对象包装您的模型对象并提供更适合绑定(bind)的数据和行为。这个包装器对象也被认为是一个 View 模型,拥有它们会导致一个“更厚”的 View 模型层,在那里你的 View 永远不会直接绑定(bind)到模型类上的任何东西。集合将包含包装模型的 View 模型,而不仅仅是包含模型本身。

  • 兔子洞更深 - 有很多习惯用法需要弄清楚,例如保持 MVVM 工作的 ValueConverters,当您开始考虑诸如 Blendability、测试以及如何在您的应用程序中传递数据并确保每个 View 模型都可以访问它需要的行为(这是依赖注入(inject)的用武之地),但希望以上是一个好的开始。关键是将视觉效果、领域以及实际应用程序的结构和行为视为三个不同的事物。

    关于mvvm - MVVM 的基本概念——ViewModel 应该做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5421874/

    相关文章:

    c# - 不处理 View 或 View 模型的棱镜区域

    ios - 将标签栏与 MVVM Light (iOS) 结合使用

    wpf - 响应事件时运行命令

    extjs 5如何将商店绑定(bind)到模式窗口和网格

    c# - 向 ViewModel 添加扩展方法是否维护 ViewModel 规则?

    c# - 交换控制模板

    xaml - 银光 : Not naming controls in XAML when using MVVM (Silverlight)?

    c# - 如何通过绑定(bind)到复选框来过滤表格项?

    c# - 在 Viewmodel 属性中防止 StackOverFlow 或递归

    c# - View 模型的单独项目到 "enforce"MVVM : How do I open dialogs?