18

我刚刚开始研究用于 WPF 应用程序的 MV-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 方法显示视图的逻辑在哪里?

4

5 回答 5

19

正如基夫所说:

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

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

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

替代文字

于 2008-11-20T21:27:11.190 回答
13

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

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

于 2008-11-19T21:27:12.577 回答
4

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

  • 如果您在视图中处理本地操作,则可以从视图模型开始。

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

于 2009-01-30T10:28:14.900 回答
1

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

于 2012-12-29T19:00:09.580 回答
0

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

于 2008-11-19T20:37:13.520 回答