【问题标题】:M-V-VM Design Question. Calling View from ViewModelM-V-VM 设计问题。从 ViewModel 调用 View
【发布时间】:2008-11-19 19:13:11
【问题描述】:

我刚刚开始研究用于 WPF 应用程序的 M-V-VM。到目前为止,除了这个特定问题之外,一切都有意义......

我有一个 ViewModel,我将其称为 Search。此 ViewModel 绑定到数据网格并列出项目的结果。现在,我有一个命令需要调出另一个视图,即项目的详细信息。

将逻辑放在搜索视图中显示另一个视图似乎不正确,根本无法测试。

这是我的 ViewModel 实现,不可测试...

public class SearchViewModel
{
   public void SelectItem()
   {
     // I want to call the DetailsView from here
     // this seems wrong, and is untestable
     var detailsView = new DetailsView();
     detailsView.Show();
   }
}

从 ViewModel 方法显示视图的逻辑在此模式中的位置在哪里?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    正如基夫所说:

    视图不应在 UI 层“下方”的任何地方实例化。虚拟机存在于该领域之下,因此这不是放置该逻辑的地方(正如您已经意识到的那样)。

    几乎总会有一些用户界面 级别事件,将指示 需要创建视图。在你的 例如,它可能是一行(双) 数据网格上的单击事件。那 将是新的和展示的地方 您的 DetailsView 窗口。

    您必须意识到 M-V-VM 与 MVC 或 MVP 等其他模式略有不同。 ViewModel 对 UI 没有直接的了解。打开另一个视图是视图特定的功能。视图模型应该不太关心什么或多少视图正在使用它的数据。我很可能永远不会通过命令打开视图。

    【讨论】:

      【解决方案2】:

      视图不应在 UI 层“下方”的任何地方实例化。虚拟机存在于该领域之下,因此这不是放置该逻辑的地方(正如您已经意识到的那样)。

      几乎总会有一些 UI 级别的事件表明需要创建视图。在您的示例中,它可能是数据网格上的行(双击)单击事件。那将是更新并显示您的 DetailsView 窗口的地方。

      【讨论】:

      • 感谢您的帮助,这似乎是一个可行的解决方案。尽管我无法对设置视图的逻辑进行单元测试(设置与注入的 ViewModel 交互的属性),但它使 ViewModels 可测试,这是大部分逻辑所在。
      • 如果一个简单的事件打开视图,这很好。但是,如果事件需要更多操作、数据获取、验证怎么办。你也会把这些东西放到视图中吗?或者创建另一个级别的间接?
      • 确实如此。和山姆在这里有同样的问题。如果在打开视图之前需要更多数据或逻辑怎么办? (例如,如果属性 x=1 打开视图 1,如果属性 x=2 打开其他视图)
      • @Sam @Tom:事件的参数将传递 UI 所需的任何数据。然后,处理程序使用该数据做出决定,和/或检索更多数据。我喜欢将我的事件处理程序放在控制器上,以使我的虚拟机尽可能轻。看看 Prism 2.0 中的事件聚合和命令模式就是一个很好的例子。它实际上展示了几种不同的方法。
      【解决方案3】:

      这是一个基本的经验法则。

      • 如果您正在处理本地操作 你的观点,你可以从 视图模型。

      • 如果是交叉视图(例如显示搜索屏幕),则使用 E​​ventAggregator 模式(事件服务)或注入您调用方法的应用程序控制器,然后它会显示搜索。

      【讨论】:

        【解决方案4】:

        Catel 包括一种涉及使用IUIVisualizerService 的方法。此接口定义了一个 UI 控制器,可用于从 ViewModel 以模态或非模态形式显示对话框。基本上,在父 vm 中,您创建应该保留在新视图后面的视图模型,服务会找到关联的视图模型(基于某些约定或注册),然后显示它。

        【讨论】:

          【解决方案5】:

          我们使用这种模式的一个变体,这里我们有代表 VM 的控制器,因此视图的数据上下文是 VM,我们的 DTO 是 VM/控制器的属性。我们仍然称它为控制器,因为我们使用它作为控制点,从而处理来自视图的某些命令。这是(我认为)我们将执行您的命令的地方。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-30
            • 1970-01-01
            • 1970-01-01
            • 2010-09-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多