【问题标题】:Doubts in MVVM pattern?对 MVVM 模式有疑问?
【发布时间】:2011-07-25 03:53:38
【问题描述】:

我正在创建一个 WPF 应用程序并遵循 MVVM 模式。但是在做事情的时候我很担心,是不是根据MVVM?有这些疑惑请指教。

  1. 是否有必要为每个视图创建一个新的视图模型?如果不是,那么创建单个 MasterViewModel 是否违反了 MVVM?

  2. ViewModel 将如何相互通信?

  3. MainWindow.xaml.cs 我在其中集成了所有视图,应该只有 viewmodel 的初始化并在那里分配 DataContext 或者我也可以放置其他代码?

  4. 我有我定义的事件处理程序。我应该在 ViewModel 中还是在 model-view-viewmodel 之外使用它们?

【问题讨论】:

    标签: c# wpf mvvm c#-4.0


    【解决方案1】:

    您需要阅读一些有关 MVVM 的内容。请参阅以下问题:

    Good examples of MVVM Template
    Good Silverlight-MVVM Practice Example
    MVVM Light Toolkit samples

    对于您的问题:

    1. 有些人遵循这个规则。 : One-ViewModel-Per-View 请参阅Rule #2 on this article

      这不是绝对必要的,但是创建一个 MasterViewModel 以在任何地方使用它,意味着你还没有理解 MVVM。

      如果您指的是封装公共位,那么 MVVM Light Toolkit 可能有一个 ViewModelBase 类来封装一些东西。

    2. ViewModels 不会相互通信,ViewModels 将与 Views 通信,而 Views 将与其他 Views 通信(并可能为它们实例化 ViewModels)一些框架甚至有松散耦合的方式来做到这一点(@987654326 @ 浮现在脑海中)

    3. 当调用视图时,您可以实例化其对应的 ViewModel,然后将其设置为 DataContext。 但是,这样做有很多不同的模式。 @Euphporic 在 cmets 中提到 ViewModel-first,ViewModels 通过 Ioc 创建视图。见Which came first- The View or ViewModel

      MVVM Light 有一个 ViewModel 定位器,它允许您在 XAML 中静态定义一个 Views ViewModel。它会在您创建视图时自动设置。

    4. 这里不完全清楚,(a)如果你有来自按钮、菜单的事件(任何从 ButtonBase 派生的)你应该使用命令模式来实现这些。 MVVM Light 有一个很好的RelayCommand<T>,可以在这里为您提供帮助。

      (b) 其他事件,MVVM Light 具有 EventToCommand 行为,但 Laurent(作者)警告这会变成反模式。我认为有时您可以在后面的代码中使用普通事件,然后从那里调用您的 ViewModel(但是,嘿,我不是这里的专家)


    您到处都问了几个问题。问题可能你对MVVM的WHY不了解。

    简单来说,MVVM 允许您将正确的东西放在正确的位置,将您的应用程序逻辑/控制保存在 ViewModel 中,然后借助 Silverlight/WPF 数据绑定的强大功能,您可以将 ViewModel 连接到您的视图。

    正如Laurent 解释的那样,有时它不必那么复杂。您甚至不需要一直使用框架。

    我强烈推荐从这里观看他的 MIX 视频 - “了解模型-视图-视图模型模式”
    http://live.visitmix.com/Archive#VideoList

    【讨论】:

    • “视图(并可能为它们实例化 ViewModel” 不在 ViewModel-first 场景中。
    • 谢谢@giddy...我知道我没有清楚地理解MVVM,但由于某种原因我开始研究它。无论如何,这次我会得到它并以更好的方式实施
    • @giddy 2.ViewModels 不会相互通信 如何解决这样的问题,一个视图模型有任何变量,而我想要改变的 var 值其他视图模型
    • @Gaps 大多数框架都有通信方式,MVVMLight 有一个信使类可以用来发送变量。
    • 请记住视图模型引发PropertyChanged。您可以使用这一事实在大多数情况下实现视图模型间通信,而无需引入规则 2 旨在避免的依赖类型。
    【解决方案2】:

    是否有必要为每个视图创建一个新的视图模型?如果不是,那么创建单个 MasterViewModel 是否违反了 MVVM?

    不,您可以在单个视图模型上拥有多个视图,尽管通常具有一个视图模型与一个视图的关系。如果您正在考虑为所有视图使用一个主视图模型,那么它很快就会变得难以管理。

    所有 ViewModel 将如何相互通信?

    有多种方法,包括视图模型、标准 .NET 事件或事件聚合器模式之间的直接引用。

    MainWindow.xaml.cs,我在哪里 整合所有的意见,应该有 只有viewmodel的初始化 并分配 DataContext 将 那里或者我也可以放其他代码?

    通常在 MVVM 中,您不需要(或很少)代码,而是在 WPF 应用程序中使用 XAML 绑定引擎来进行视图模型/视图通信。

    我有我定义的事件处理程序。 我应该在 ViewModel 中使用它们还是 在模型-视图-视图模型之外?

    不太清楚您的意思,但如果需要,您可以使用标准事件进行视图模型通信。

    我会认真考虑为您的应用使用 MVVM 框架,我个人的偏好是 Caliburn.Micro

    【讨论】:

      【解决方案3】:

      [1] 是否有必要为每个 View 拥有一个新的 ViewModel?如果 不是,那么可以创建一个 MasterViewModel 是否违反了 MVVM?

      通常您需要为每个 View 实例创建一个新的 ViewModel 实例,并为每个 View 类创建一个不同的 ViewModel 类。有时您希望同一个 ViewModel 有多个 View,这没关系。如果您使用 ViewModel-first 方法,那么您可能并不总是需要为每个 ViewModel 类创建一个 View 类,但拥有一个也没有什么坏处。

      [2] ViewModel 将如何相互通信?

      如果 ViewModel 直接相关(例如父/子关系),那么一种可能性是其中一个直接引用另一个,或者一个订阅另一个事件。

      如果 ViewModel 在逻辑上是独立的,那么您应该使用一些其他机制,例如 Event Aggregator(在 Prism 中)或 Messenger(MVVM Light)或等效机制。

      [3] 我正在集成所有视图的 MainWindow.xaml.cs 应该有 只有viewmodel的初始化 并分配 DataContext 将 那里或者我也可以放其他代码?

      您不应在 View 代码隐藏中初始化 ViewModel。模型应该通过依赖注入 (DI) 容器注入到视图中。

      [4] 我有我定义的事件处理程序。我应该在 ViewModel 或外部 模型-视图-视图模型?

      我不明白你在这里问什么。

      【讨论】:

      • +1 好答案。对于(3)你认为那总是必要的,即使你有强类型的VM,彼此没有关系?你会为每个 VM 提供接口吗?
      • @jon....你能提供任何示例代码或链接吗?我没有得到任何关于 DI 的示例,因为我知道后面的视图代码不应包含任何与行为相关的代码...
      • @GAPS:在 Wikipedia 中查找 Inversion of Control(第一)和 Dependency Injection(第二)——有很好的简短介绍以及参考和更多链接。
      【解决方案4】:

      1.是否有必要为每个 View 都有一个新的 ViewModel?如果不是,那么创建单个 MasterViewModel 是否违反了 MVVM?

      不是真的。您可以拥有与大量视图相对应的特定视图模型,每个视图以不同的格式显示相同的数据。事实上,这首先是 MVVM 的全部基本原理——显示和业务规则的分离,以便可以通过加载不同的视图来更改显示格式。

      您还可以拥有一个对应于多个不同 ViewModel 的 View。这是显示 UI 上的代码重用。

      2. ViewModel 将如何相互通信?

      通常 ViewModels 通过 WPF Binding 与 Views 通信。这就是为什么它被称为 MVVM 而不是 MVC。

      ViewModel 可以通过多种标准 .NET 方式相互通信。

      3.我正在集成所有视图的 MainWindow.xaml.cs 应该只有 viewmodel 的初始化并在那里分配 DataContext 或者我也可以放置其他代码?

      您通常将每个视图分隔到一个单独的 XAML 文件中。这使得用另一个视图替换相同数据的不同格式变得很容易。

      通常,建议将您的代码分成独立的模块;即一个视图一个文件,一个视图模型一个文件。

      4.我有我定义的事件处理程序。我应该在 ViewModel 中还是在 model-view-viewmodel 之外使用它们?

      如果事件是纯 UI 驱动的(即与数据无关),则应在视图中处理事件。

      如果某个事件应该影响底层数据的某些更改(或对业务规则执行某些操作),您可以反过来在 ViewModel 上引发一个事件。请注意,ViewModel 上的此事件可能与 View/UI 上的事件不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-19
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        • 2011-04-14
        • 1970-01-01
        • 2020-12-30
        • 2017-02-22
        相关资源
        最近更新 更多