对MVVM模式的质疑?

时间:2011-03-29 10:11:41

标签: c# wpf mvvm c#-4.0

我正在创建一个WPF应用程序并遵循MVVM模式。但是在做事的时候我担心这个问题,它是否符合MVVM的要求?请引导这些疑惑。

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

  2. ViewModels将如何相互通信?

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

  4. 我正在使用我定义的EventHandlers。我应该在ViewModel中使用它们还是在model-view-viewmodel之外使用它们?

4 个答案:

答案 0 :(得分:3)

你需要在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)一些框架甚至采用松散耦合的方式({{ 3}}浮现在脑海中)

  3. 调用View时,可以实例化其对应的ViewModel,然后将其设置为DataContext。 但是,有很多不同的模式可以做到这一点。 @Euphporic在注释中提到了ViewModel-first,其中ViewModels通过Ioc创建了Views。请参阅ReactiveUI

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

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

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


  5. 你在这个地方问了几个问题。问题可能是你不理解关于MVVM的为什么

    简单来说,MVVM允许您在正确的位置保持正确的东西,在ViewModel中保存应用程序逻辑/控件,然后利用Silverlight / WPF数据绑定的功能将ViewModel挂钩到您的视图。

    正如Which came first- The View or ViewModel所解释的那样,有时它并不一定非常复杂。你甚至不需要一个框架。

    我强烈建议观看他的MIX视频 - “了解Model-View-ViewModel模式”从这里:
    Laurent

答案 1 :(得分:2)

  

是否需要为每个View创建一个新的ViewModel?如果没有,那么创建单个MasterViewModel是否违反MVVM?

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

  

所有ViewModel如何相互通信?

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

  

MainWindow.xaml.cs,我在哪里   整合所有的观点,应该有   只有viewmodel的初始化   并分配DataContext将   那还是我还可以放其他代码?

通常在MVVM中,你没有(或很少)代码,并且在WPF应用程序中使用XAML绑定引擎代替viewmodel / view通信。

  

我正在使用我定义的EventHandlers。   我应该在ViewModel中使用它们还是   在model-view-viewmodel之外?

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

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

答案 2 :(得分:2)

  

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

通常,每个View实例都需要一个新的ViewModel实例,每个View类需要一个不同的ViewModel类。有时您需要同一ViewModel的多个视图,这是可以的。如果你使用ViewModel-first方法,那么你可能并不总是需要为每个ViewModel类提供一个View类,但是拥有一个View类也不会受到伤害。

  

[2] ViewModels将如何相互沟通?

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

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

  

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

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

  

[4]我正在使用我定义的EventHandlers。我应该使用它们吗?   ViewModel或以外的   模型 - 视图 - 视图模型?

我无法理解你在这里问的是什么。

答案 3 :(得分:1)

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

不是真的。您可以拥有与大量视图对应的某些ViewModel,每个视图以不同的格式显示相同的数据。事实上,这首先是MVVM的基本原理 - 显示和业务规则的隔离,以便通过加载不同的视图来改变显示格式。

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

2。 ViewModels将如何相互通信?

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

ViewModels可以通过许多标准的.NET方式相互通信。

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

您通常将每个视图分成单独的XAML文件。这样可以很容易地将另一个视图替换为相同数据的不同格式。

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

4。我有我定义的EventHandlers。我应该在ViewModel中使用它们还是在model-view-viewmodel?

之外使用它们

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

如果某个事件会影响基础数据的某些更改(或对业务规则执行某些操作),则可以在ViewModel上引发事件。请注意,ViewModel上的此事件可能与View / UI上的事件不同。