在大型应用程序中使用MVVM - 共享视图模型、模型、状态等

13

我在想,是否有人知道一些关于大型应用程序中MVVM的好教程。我找到的所有有关MVVM的教程都只是解释基础知识(如何实现模型、视图模型和视图),但对于在应用程序页面之间传递数据的技术和模式,以及初始化视图模型的位置、存储公共应用程序数据(在多个视图模型之间共享)等方面的问题我很感兴趣。

我更喜欢没有任何MVVM框架(例如MVVMLight)的纯c#/XAML解决方案。


1
太泛泛的问题难以回答,一般人会选择与他们所选择的框架相吻合的设计 - 很难找到不针对特定框架的即插即用解决方案。 - Jon
1
如果我能理解这个思路/模式,那么针对特定框架的解决方案也会对我有用。 - user969153
很遗憾,我担心你找不到你要寻找的答案。99%的MVVM“示例”只是玩具,只能(勉强)回答简单的问题。我还没有找到任何大型、严肃的应用程序样本。 - Jack Ukleja
3个回答

11

在应用程序页面之间传递数据的技术和模式

如果数据传递是事件驱动的(即:您希望在从服务器推送的数据接收时通知),请使用弱事件。Prism的EventAggregator是许多实现之一。

如果数据传递是常量,请让DataContext沿着XAML树向下流动并简单地使用绑定。
这意味着,如果您有一个“主”UserControl,它使用其他更具体的UserControl,不要设置它们的DataContext,它们将继承主元素的DataContext,一切都很好。
如果您想分离功能,请在主ViewModel中使用组合。

在哪里初始化视图模型

纯粹主义者会告诉你在XAML中直接实例化它们。我几乎从不这样做。
首先,ViewModel通常需要服务,并且它们作为构造函数参数传递或通过MEF注入到构造函数中等等。因此,您不能有无参数的构造函数或者它更难写。

现在,我们可以做困难的事情,但是有什么好处呢?让视图的代码后台检索ViewModel或在构造函数中注入它是完全可以的。

在哪里存储应用程序通用数据(在多个视图模型之间共享)

如果数据是全局的:使用静态类/属性,
在XAML中,您可以通过{x:Static my:StaticClass.StaticProperty}访问它们,如果要访问嵌套类/枚举,请使用+而不是.

如果数据仅在几个ViewModel之间共享而不是全部,则在ViewModel中使用继承/组合以及控制器模式。

从经验中获得的其他提示:

  • 仅绑定您需要的内容:当您只需要其中的一个字符串时,不要将整个对象绑定。

  • 如果您一遍又一遍地绑定同样的东西,请毫不犹豫地制作自定义标记,继承自Binding/MultiBinding。这是DRY 101,但大多数人出于某种原因只是复制/粘贴绑定。

示例:

public class VisibilityBinding : MultiBinding, IMultiValueConverter
{
   public VisibilityBinding()
   {
      var isSomething = new Binding("IsSomething");
      isSomething.ElementName = myUsrCtrl;
      this.Bindings.Add(isSomething);

      //Add more bindings

      this.Converter = this;
    }

    //Implement IMultiValueConverter to compute a System.Visibility from the bound values.
}

在XAML中:

 <TextBox Visibility={customMrkup:VisibilityBinding} />
  • 尽可能避免数据重复,一直到数据访问层(DAL)。通过使用I(Multi)ValueConverter可以简单地推导出一些字段,因此同步这些字段会变得非常复杂。
    例如:您有一个音频文件,它有一个开始时间、结束时间和持续时间。如果去掉这三个属性中的任何一个,第三个属性都可以被推导出来。

如果我想到更多的建议,我会回来添加的。

希望这能帮到你!


非常好的详细回答,谢谢。但是,如果您能推荐一些关于“在XAML树中传递DataContext”和“视图模型上的继承/组合以及控制器模式”的更多信息链接,那将非常有帮助。 - user969153
让DataContext流动不需要你做任何事情,这是默认的。在VM中继承/组合是拥有一个公共字段来保存一些数据,而这些数据首先来自于一个控制器的分发。 - Louis Kottmann
我也同意需要一些示例。我有一个非常复杂的、五级嵌套的数据源——这确实需要如此详尽地表示,而且无法找到任何适当的方法在“正确”的mvvm中表示它。这并没有帮助DAL是内部(为MS Access),而模型类是通过自定义生成器构建的。 - Richard Griffiths

2
你可能想看一下这本书:Building Enterprise Applications with Windows Presentation Foundation and the Model View ViewModel Pattern(例如在Amazon.com上)。它从更广泛的视角来介绍MVVM,而不仅仅是一个5分钟的代码片段,并且甚至提供了如何组织业务解决方案的建议。我们经常在工作中将其用作参考。个人认为,希望它能深入一些细节。但是,从面向业务应用程序的角度进入MVVM,这是一个不错的阅读材料。
描述文本: 使用MVVM设计模式创建丰富、灵活和可维护的业务应用程序 通过将MVVM模式应用于Windows Presentation Foundation(WPF)和Microsoft®Silverlight®4,简化并改进业务应用程序开发。通过数据绑定、命令和行为使用MVVM,创建与业务逻辑松耦合的用户界面。MVVM非常适合使用WPF和Silverlight的.NET开发人员,无论您是否有构建企业应用程序的经验。
了解如何:
- 深入了解MVVM,以及它与其他UI设计模式的区别 - 构建一个简单的客户关系管理应用程序,您可以根据自己的项目进行调整 - 实施MVVM以保持UI声明语法和演示逻辑代码之间的分离 - 创建领域模型来定义应用程序的业务上下文 - 使用Microsoft Entity Framework和NHibernate编写数据访问层的动态代码 - 利用Windows Workflow Foundation 4执行复杂的数据验证场景 - 使用Microsoft Prism等框架和工具包实现MVVM

1

首先,您可以创建一个BaseViewModel,其中包含所有ViewModel中通用的一些属性。使用依赖注入,例如Castle / Prism4,将数据从一个ViewModel发送到另一个ViewModel,我们使用了Prisms EventAggregator。希望这能帮助您完成任务。但正如Jon所说,完全取决于您喜欢使用什么。但这些都是很好的起点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接