代码之家  ›  专栏  ›  技术社区  ›  Jab

M-V-VM设计问题。从ViewModel调用视图

  •  18
  • Jab  · 技术社区  · 17 年前

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

    我有一个ViewModel,我称之为搜索。此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方法显示视图的逻辑在哪里?

    5 回复  |  直到 17 年前
        1
  •  19
  •   Glorfindel Doug L.    4 年前

    正如Kiff所指出的:

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

    几乎总是会有一些UI 级别事件,将指示 需要创建视图。在你的 例如,它可能是一行(双行) 单击datagrid上的事件 将是新事物和展示的地方 您的详细信息视图窗口。

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

    alt text

        2
  •  13
  •   Chris Staley    17 年前

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

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

        3
  •  4
  •   Glenn Block    16 年前

    这里有一个基本的经验法则。

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

    • 如果是交叉视图(如显示搜索屏幕),那么要么使用EventAggregator模式(事件服务),要么注入一个应用程序控制器,您可以在其上调用方法,然后它反过来显示搜索。

        4
  •  1
  •   g1ga    12 年前

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

        5
  •  0
  •   Preet Sangha    17 年前

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