【问题标题】:MVVM, collections and ORMMVVM、集合和 ORM
【发布时间】:2010-12-09 23:16:26
【问题描述】:

我试图将 MVVM 设计模式与 WPF 和实体框架一起使用来创建一个简单的应用程序。如果这些类是松散耦合的,那么一切都很好,但是如果我有的话。像两个模型类:客户和地址,客户有一个地址集合。

现在对于这些类,我需要创建两个 VM 类 - CustomerVM 和 AddressVM。 CustomerVM 应该有 AddressVM 对象的 ObservableCollection。对这些 VM 类(包括 CustomerVM 和 AddressVM 上的所有 CRUD 操作)所做的每一项更改都需要反映在模型类中——这就是为什么我最终编写了一堆代码,例如。订阅 ObservableCollection 的 changed 事件,如果添加了新对象,则将新对象添加到模型中......等等......

怎么办?这在使用 MVVM 时是否常见?我做的一切都好吗?如何减少如此简单的类层次结构所需的代码量?是否有任何框架可以创建与层次结构中的其他类“表现良好”的基本 VM 类?如果类关系变得更复杂怎么办?

或者说简单点:

如何在模型集合中反映 vm 集合中所做的更改:

CustomerVM1.AdressesVM.Add(new AddressVM{City="New York"}) 

应该导致相当于:

Customer1.Adresses.Add(new Address{City="New York"})

反过来也有同样的问题 - 如何反映对模型中的集合所做的更改以包含在视图模型中,但我对第一个更感兴趣,因为它具有更实际的应用程序和 vm在大多数情况下,对象可以简单地重新创建。

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    您可能对 WPF Application Framework (WAF)BookLibrary 示例应用程序感兴趣。它展示了如何一起使用 Entity Framework 和 MVVM。

    简短提示:它不会为每个实体类创建包装 ViewModel。相反,它会为视图创建 ViewModel 类。

    【讨论】:

      【解决方案2】:

      当我试图弄清楚如何在我的 ViewModel 中保持 ObservableCollection 与我的模型中的普通旧集合同步时,您遇到了完全相同的问题。 ObservableCollection 很棒,因为 View 可以绑定到它并在集合更改时自动更改。不幸的是,您刚刚将同步问题降低了一级。

      一种选择是在任何地方都使用 ObservableCollections,即使在模型中也是如此。这不是很干净的架构,因为 MVVM 不应该对模型提出任何要求。

      我为解决这个问题所做的就是引入一个 Presenter,所以我的架构如下所示:

      View -> ViewModel <-> Presenter <-> Model
      

      另外,我让我的 ViewModel 。以下是典型的用户操作从开始到完成的过程:

      1. 用户点击添加按钮
      2. ViewModel 要么引发 Presenter 订阅的事件,要么调用 Presenter 上的方法,或者只是调用 Presenter 在构造 ViewModel 时提供给 ViewModel 的回调。本质上,它将操作委托给 Presenter。
      3. Presenter 在模型上调用 Add。
      4. 模型对 Add 调用做出反应,更新它的所有相关状态,包括 plain-old-collection。
      5. 演示者在模型上执行了操作,然后从模型中读取新状态并将状态写入视图模型。绑定负责同步视图。

      因此,在您的情况下,Presenter 可以订阅 ViewModel 中 ObservableCollection 上的 CollectionChanged 事件,当它发生变化时,它会通过调用模型上的 Add 来响应该事件。另一方面,当 Presenter 正在处理在模型上调用 Add 的其他用户操作时(它知道是因为它处理与模型的所有交互),那么它知道它必须传播该更改到 ViewModel 中的ObservableCollection

      在我的代码中,我简化了情况...在演示者对模型执行每个用户操作后,我将模型中的所有相关状态直接复制到适用的位置在视图模型中。您所做的工作比您需要的要多,但在典型的 CRUD 类型的应用程序中,没有明显的性能问题。如果我有一个非常大的对象集合,性能可能会成为问题,我会降低到更细粒度的同步(仅更新更改的实体),但会牺牲更复杂的逻辑。

      【讨论】:

      • 非常感谢您的精彩回答。这当然是解决问题的一种方法,但是 IMO 并没有真正让你编写更少的代码——它是一种更清洁的方法。你仍然需要另一个层的 Presenter,事情变得比他们想象的要复杂。
      • 昨天我正在考虑做类似“减少”的 mvvm 之类的事情——我不想创建 VM 类,而是想通过使用部分类来扩展模型类。现在,对于我需要的每个属性,我都可以创建另一个封装旧属性的属性 - 与 MVVM 中的相同。对于一个普通的旧集合,我可以只创建一个实现 INotifyCollectionChanged 并使用普通旧集合进行存储的包装器集合。你怎么看?
      • 我在想的另一件事可能是创建一个像 MyCollection 这样的通用集合 -> 这个应该知道关于模型viewmodel 交互所需的一切,并且能够处理您在演示者中所做的一切。如果写得好,它可以在任何地方重复使用。
      猜你喜欢
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 2023-03-17
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2012-04-27
      相关资源
      最近更新 更多