【问题标题】:How should I implement multiple views on the same data?我应该如何对同一数据实现多个视图?
【发布时间】:2011-06-30 15:43:21
【问题描述】:

我有一个基于 MVVM/WPF 的应用程序,它可以同时打开多个工作区(基本上包含一个 TreeView),这些工作区在同一数据树上显示和操作。我需要能够独立展开和折叠并选择每个工作区中的项目,并且我希望能够在两个工作区之间拖放项目(例如,用于移动或复制项目)。我还需要数据虚拟化,因为只有在第一次展开树项时才加载数据(在两个视图中)。还有一个工作区范围的详细信息视图,显示当前具有焦点的工作区的选定项目的详细信息。工作区特定的扩展和项目选择也必须以编程方式工作。

您能否为包含这些功能的基于 MVVM 的应用程序设计一个 ruff 设计?我应该为每个工作区创建一个单独的 ViewModel 树并实现一个 Model-ViewModel 映射器吗?或者我应该只有一个带有两个视图的 ViewModel 树?详细信息视图如何知道当前选择了什么以及哪个工作区具有焦点? ...

所以改写我的问题:每个视图中显示的模型实例实际上是相同的实例。但是 ViewModel 也应该相同吗?或者更好:我能侥幸逃脱吗?

另外:有没有我可以研究的具有大部分这些功能的开源应用程序? Prism 或任何其他基于 MVVM 的框架可以为我完成大部分工作吗?

【问题讨论】:

    标签: wpf architecture mvvm software-design


    【解决方案1】:

    View 和 ViewModel 之间存在直接关联。视图显示模型的可视化表示,由 ViewModel 托管和“格式化”。

    由于每个视图上都有不同的模型(数据),因此您需要有多个 ViewModel 实例来托管每组不同的数据。

    现在的问题是:您的 ViewModel 是否在它们之间共享一些实体或对象? 如果是,它们会在您的应用程序生命周期内发生变化吗?您想在 TreeView 中实时查看这些变化吗?

    然后你有两个选择:

    1. 通过您的 ViewModel 公开模型,直接将模型绑定到视图(如果模型实现 INotifyPropertyChanged):那么当模型属性更改时,您的所有视图都将自动更新。
    2. 创建一个组件来监督模型修改并通知 ViewModel 公开它们。

    第二个解决方案比第一个更纯粹,因为模型应该是 POCO 并且不应该实现一些面向管道的接口。 ViewModel 应该处理管道。

    但是设计起来更复杂,而且 90% 的情况下,你最终会说“来吧,只要一个小界面就不会受伤”:)

    用于您的详细信息视图。您可以使用中介器(MVVM Light Toolkit 中的 Messenger)在 TreeViewModel 和 DetailViewModel 之间进行通信,中介器基本上是一个低耦合的面向事件的组件。或者使用注入到所有 ViewModel 中的主管并使用事件通知他们。

    说到 MVVM 框架,对于像你描述的那样的通用架构,我推荐MVVM Light Toolkit

    【讨论】:

    • 所以你说我应该走多视图模型路线?只是为了确保:我在每个视图上没有不同的模型(数据)。我有多个视图一个 same 数据(模型)。每个 View 中显示的 Model 实例实际上是相同的实例。但是 ViewModel 也应该相同吗?或者更好:我能侥幸逃脱吗?
    • 如果我理解你的话,你想在不同的树视图之间启用拖放。因此,封装在 ViewModel 中的项目集合可能会发生变化。有些人会丢失物品,有些人会得到一些。那么你不能为所有视图拥有一个 ViewModel,因为每个 ViewModel 的集合不相等。我认为可能存在一些例外情况,您可以在非常简单的场景中摆脱 ViewModel。但这意味着您已将管道放入模型中。但再一次,这应该是 ViewModel 的工作。无论如何,它似乎不适合您的场景。
    • 等待:如果我从一个 VM-tree 拖动到另一个基于相同模型的 VM-tree,拖放仍然会导致两个 VM-tree 具有完全相同的数据。所以两棵树将总是具有完全相同的数据结构,不是吗?只是它们的扩展和选择状态不同。在两个 ViewModel-tree 之间拖放只是在 same Model-tree 中移动或复制项目。
    • 我必须说我不太关注你。当您将一个项目从 TreeView 1 拖动到 TreeView 2 时,该项目将从绑定到 TreeView 1 的集合中删除并添加到 TreeView 2。绑定的数据不一样,因此它们无法链接到相同的 ViewModel(或带有管道的模型 :)
    • 当我将项目从一棵树拖到另一棵树时,两棵树都没有任何变化。只有当我删除项目时,才会应用更改。但是这些变化会在两棵树中同样发生,因为它们代表相同的模型树。删除该项目将立即修改 唯一的模型树。拖放后两棵树看起来仍然完全相同,因为它们代表非常相同的模型树。我刚刚对拖放操作所做的是将项目从一个位置移动到另一个位置在同一模型树中
    【解决方案2】:

    也许我遗漏了一些东西,但不可能让同一个 View / ViewModel 的 2 个实例加载不同的数据吗?

    【讨论】:

    • 是的,这是可能的。我有一个模型(数据树),但需要两个相当独立的视图。我应该有两个指向同一个模型的 ViewModel 树(每个视图一个)吗?或者我可以摆脱绑定到 2 个视图中的一个 ViewModel 树吗?我的问题是针对上述相当普遍的要求的总体“最佳实践”。
    猜你喜欢
    • 1970-01-01
    • 2010-11-10
    • 2013-01-24
    • 2020-04-27
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    相关资源
    最近更新 更多