【问题标题】:How to create the ViewModel(s) for many Views sharing the same Model?如何为共享同一模型的多个视图创建 ViewModel(s)?
【发布时间】:2011-07-19 20:54:25
【问题描述】:

这是基于书中的示例: Gary McLean Hall 的 Pro WPF 和 Silverlight MVVM

作者只坚持如何为数据库结构创建模型(以及如何为它实现 DAL)。

我正在寻找创建 ViewModel(s) 的正确方法。

这是database model and the MVVM Model- 我怀疑它不是很完整,但是产品缺少产品代码:

我的视图将是:显示/编辑产品、客户和订单视图的页面 我熟悉实现/使用 INotifyPropertyChange 和 ObservableCollection 的模型/视图模型,无需坚持。

我的问题:

  1. 如何创建 ViewModel 以使它们共享相同的模型
  2. 如何管理 ViewModel?我是否有一个聚合所有特定视图的主视图模型?这与 ViewModel 状态保存和恢复有关。

我对如何处理这个问题特别感兴趣:订单模型有一个产品列表。我还必须为我的 ProductsViewModel 维护一个产品列表,该列表支持产品的显示/编辑视图。怎么能全部同步? OrderModel 是否应该只有一个 ProductCode 列表?在这种情况下会有什么影响?

一般来说,我在这里追求的是:如何为实现具有多对多关系的数据库表(如产品订单)的模型创建和管理 ViewModel。我们是只使用外键作为模型对象的一部分,还是使用对由该外键表示的整个其他模型对象的引用?

【问题讨论】:

  • 保持每个 ViewModel 独立和轻量级是要走的路。根据向用户显示的视图加载适当的视图模型。
  • 你能给我一个简单的例子来实现一个视图的 OrderViewModel 显示给定客户的订单列表。 ViewModel 应该如何引用 Model?

标签: silverlight windows-phone-7 mvvm


【解决方案1】:

对我来说,这听起来像是你想错了方向。当您问“如何为实现具有多对多关系的数据库表的模型创建和管理 ViewModel”时,听起来您是在从模型的角度考虑 ViewModel。这是不对的。 ViewModel 是 View 的模型,而不是 Model。你不应该考虑为你的模型创建 ViewModels,你应该考虑为你的 Views 创建 VewModels。

事实上,模型直到最后才出现。从您的 UI 开始 - 您的视图。然后,您可以在代码中创建该视图的逻辑表示,以便您可以绑定到它,即您的 ViewModel。最后你通过访问你的模型来实现你的 ViewModel 来做任何需要做的事情。当你开始设计下一个 View 时,即使它可能包含一些与第一个相同的数据,你仍然会为它创建一个新模型 - 另一个 ViewModel。现在新的 ViewModel 可以在第一个 ViewModel 中包含一些相同的属性,这很好。记住 is 是 View 的 model 而不是 Model。

考虑一个电子邮件应用程序,它有 2 个视图、摘要和详细信息。因为有 2 个不同的视图,所以即使它们都从同一个底层模型中提取数据,您也有 2 个不同的视图模型。

Model                SummaryViewModel       DetailsViewModel
-----                ---------------        ----------------
RecipientAddress                            RecipientAddress
SenderAddress        SenderAddress          SenderAddress
Subject              Subject                Subject
Content                                     Content

现在摘要视图只是一个摘要,不显示收件人地址或内容,因此这些属性在 SummaryViewModel 上不存在。详细信息视图显示更多信息,因此具有更多属性。同样的想法回答了您关于外键的问题。外键在您的 View 上永远不可见,因此您的 ViewModel 成员没有任何业务。您的 ViewModel 只关心 View 所需的内容。

回答您的问题“您如何管理视图模型”:您没有。你不必。 ViewModel 实例通常(并非总是)与视图具有一对一的关系,因此您不需要管理它们。只要视图存在,它们就会存在。您只需在加载 View 时创建 ViewModel 的新实例(通常在 OnNavigatedTo 事件处理程序中,见下文)并将其存储在 View 的 DataContext 中。如果加载了两个 View 实例,则有两个 ViewModel。当 View 被 GC 处理时,ViewModel 也会被 GC 处理(如果不是内存泄漏)。

最后,关于您应该如何同步更改,这在可能同时显示许多视图的桌面 Silverlight 应用程序中可能会很棘手。幸运的是,在 Windows Phone 上,我们通常一次只打开一个视图(尽管并非总是如此)。所以我们可以简单地告诉我们的 ViewModel 在每次页面导航到时刷新:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    if (DataContext == null)
         DataContent = new MyViewModel();  //Create new instance of the ViewModel
    else
         (MyViewModel)DataContext.Refresh();  //Refresh the existing ViewModel
}

这在大多数情况下都适用于更高级的场景,您可以查看由 Prism 或 MvvmLight 等工具包提供的消息传递基础设施。

希望这有帮助。

【讨论】:

  • 关于 View - ViewModel 关系,我读得很清楚。我感兴趣的是 ViewModel - Model 关系:“最后你通过访问你的 Model 来实现你的 ViewModel 来做任何需要做的事情。” - 这里要考虑什么,不同视图之间如何共享模型,包括那些将修改数据的视图。目前,我不考虑使用任何提到的工具包。
  • 很好,你不需要工具包来做 MVVM。有很多方法可以在不同的 VM 之间共享模型。例如,您可能会遵循类型存储库模式 (msdn.microsoft.com/en-us/library/ff649690.aspx)。根据您的场景,您可能只是在 ViewModel 中新建模型对象。我经常在我的应用程序中创建类服务来处理模型的创建和缓存(与存储库模式不同),这些服务可以根据 ViewModel 的要求进行请求。
  • 我大致了解了这个想法,但让我们根据前面介绍的对象模型来举这个具体的例子。
  • 我大致了解了这个想法,但是让我们根据前面介绍的对象模型来举这个具体的例子。让我们以 ProdcutViewModel 和 OrdersViewModel 为例。前者将创建 Product 类的实例,我可以在视图中编辑该实例。 OrdersViewModel 将有一个订单集合,从而在订单中创建重复的 Products 实例。
  • 所以我正在寻找一种简单的方法来同步 Product 模型,这样 OrdersViewModel 会自动看到 Product 的变化。而且我想在不与数据库同步的情况下执行此操作(同步将手动完成,例如当用户想要时)。有没有办法以简单的方式实现这一点,除了模型和使用它们的视图之间的某种消息传递,这听起来非常复杂......我正在寻找 ViewModels 的智能设计以简化模型同步到最低限度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
相关资源
最近更新 更多