我刚刚开始研究用于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方法显示视图的逻辑在哪种格局中?
答案 0 :(得分:19)
正如Kiff所说:
视图永远不应在UI层“下方”的任何位置实例化。虚拟机存在于该领域之下,因此这不是放置该逻辑的地方(正如您已经意识到的那样)。
几乎总会有一些UI 水平事件,将指示 需要创建视图。在你的 例如,它可能是一行(双) 在datagrid上单击事件。那 将成为新人和展示的地方 你的DetailsView窗口。
你必须意识到M-V-VM与MVC或MVP等其他模式略有不同。 ViewModel没有直接的UI知识。打开另一个视图是特定于视图的功能。视图模型应该更少关注使用它的数据的视图数量或数量。我很可能永远不会通过命令打开视图。
alt text http://blogs.msdn.com//johngossman/attachment/576163.ashx
答案 1 :(得分:12)
视图永远不应在UI层“下方”的任何位置实例化。虚拟机存在于该领域之下,因此这不是放置该逻辑的地方(正如您已经意识到的那样)。
几乎总会有一些UI级别事件表明需要创建视图。在您的示例中,它可能是数据网格上的行(双)单击事件。这将是新手并显示您的DetailsView窗口的地方。
答案 2 :(得分:4)
这是一个基本的经验法则。
如果您正在处理本地操作 你的观点,你可以从中发起 查看模型。
如果是交叉视图(如显示搜索屏幕),则使用EventAggregator模式(事件服务)或注入您调用方法的应用程序控制器,然后依次显示搜索。
答案 3 :(得分:1)
Catel包含一种涉及使用IUIVisualizerService
的方法。此接口定义了一个UI控制器,可用于从ViewModel以模态或模态形式显示对话框。基本上,在父vm中,您创建应保留在新视图后面的viewmodel,并且服务找到关联的一个(基于某些约定或注册),然后显示它。
答案 4 :(得分:0)
我们在此模式上使用变体,这里我们有代表VM的控制器,因此View的datacontext是VM,我们的DTO是VM / Controller的属性。我们将其称为控制器,因为我们将其用作控制点,从而处理来自View的某些命令。这是(我认为)我们将实现像你这样的命令。