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

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

我有一个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方法显示视图的逻辑在哪里进入这种模式?

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

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

正如基夫所说:

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

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

您必须意识到MV-VM与MVC或MVP等其他模式略有不同。 ViewModel没有直接的UI知识。 打开另一个视图是特定于视图的function。 视图模型应该更少关注使用它的数据的视图数量或数量。 我很可能永远不会通过命令打开视图。

alt text http://blogs.msdn.com//johngossman/attachment/576163.ashx

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

  • 如果要在视图中处理本地操作,则可以从视图模型中进行启动。

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

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

我们在这个模式上使用了一个变体,这里我们有代表VM的控制器,因此View的datacontext是VM,我们的DTO是VM / Controller的属性。 我们将其称为控制器,因为我们将其用作控制点,从而处理来自View的某些命令。 这是(我认为)我们将在哪里实施你的命令。