使用WPF M-V-VM模式显示弹出窗口的正确方法

时间:2009-04-02 00:03:37

标签: wpf design-patterns mvvm popup

我对弹出窗口中的VM职责有疑问。 当应用程序弹出消息框或某种对话框(使用MVVM)时,我们有两个选项:

  1. 将虚拟机中的UI(ShowDialog())代码放入
  2. 让VM发送某些UI可以订阅的事件并在后面的代码中显示一个对话框(但我们正在努力争取零代码:))
  3. 你们如何处理这个案子?

8 个答案:

答案 0 :(得分:2)

不要将UI代码放在虚拟机中,这只会引起很多麻烦。

当您想要弹出窗口或对话时,通常有两种情况。要么是因为商业案例而这样做,例如双击列表的详细视图,或者它完全基于UI,例如弹出一个选项窗口。在第一种情况下,最好在VM中使用事件,在后一种情况下,我只使用事件处理程序。一个好的经验法则是,如果您不需要任何(重要的)VM变量来完成操作,那么您应该只使用事件处理程序。

最重要的是,用你的头并相信你的判断,你将很快学会使用哪个。

答案 1 :(得分:2)

结帐Onyx。这是一个基于使用服务以及服务定位器或依赖注入模式的M-V-VM库(完全公开:我是作者)。 MessageBox和常用对话框都有服务,而且添加自己的服务也很容易。

答案 2 :(得分:1)

其他人未提及的其他选项:

中继命令

VM执行我喜欢称为“中继命令”的命令。这是由其他人处理的命令,VM不关心谁。命令执行只会引发Executed事件。您的视图将订阅此事件并以新Window显示内容(内容将作为命令参数传递)。

请注意,relay命令不是routed命令。它不会在其执行逻辑中搜索处理程序。它只是引发了一个事件。

服务

如果有很多实例需要在窗口中显示内容,请编写一个处理它的UI服务。然后,VM依赖于此服务(可以轻松模拟)在Windows中显示内容。

答案 3 :(得分:1)

我想说最好的方法是在XAML中定义Popup,然后使用绑定到DataTrigger中某些条件的ViewModel来隐藏或显示它。然后,如果您关心从Popup处理返回值,请EventTrigger操纵Popup属性中的ViewModel以反映该更改。

我认为这个领域有很多话题,因为人们习惯于在WinForms世界中编程。我还没有找到一个解决方案,我需要视图中的任何代码,而不是获取初始数据或设置DataContexts

答案 4 :(得分:0)

我使用视图处理的事件。我不喜欢它100%,但它可以实现自动化测试。

答案 5 :(得分:0)

即使您打算使用messagebox,也要为弹出式对话框创建一个界面。

在视图层次结构视图的底部有一个方法供演示者注册实现弹出窗口的类或表单。

让您的观点调用已注册的弹出窗口。

答案 6 :(得分:0)

我同意卡洛斯的观点,在视图中使用事件订阅并不是一个好选择。据我了解MVVM,它导致从视图中消除任何代码,我真的很喜欢它:)。 MVVM的一个支持者是对其进行单元测试的能力。但我仍然相信,即使它弹出窗口,也可以测试视图模型。我们只需要使用具有所需视图模型的初始化内容的Window。我认为当VM应该打开新对话框时可能存在两种可能的情况:显示选项/设置窗口或显示依赖于业务逻辑的窗口。在第一种情况下,新窗口代码是命令的唯一代码(“设置”或“选项”按钮/菜单项的命令)。在第二种情况下,我们有一些决策逻辑打开窗口。但无论如何,我们可以将打开新窗口的代码移动到单独的方法/类中,并在测试我们的VM时只是为了模拟这个方法/类。更重要的是,这个单独的类可以是某种通用的WindowsController,它将跟踪应用程序中的所有窗口。但我们仍然可以说视图模型使用帮助器WindowsController打开弹出窗口,并且视图对其他窗口不了解任何其他内容。所有业务逻辑都包含在模型和视图模型中。

答案 7 :(得分:0)

具有用于弹出窗口的ViewModel和用作用户控件的View。根据弹出窗口的复杂程度,它可以是通用VM,也可以是业务案例的具体VM。当尝试从父虚拟机的VM显示它时,为弹出窗口的虚拟机创建一个“主机”类(继承自Window或Popup),显示它并将VM分配给它。主持人应负责定位正确的视图(例如,通过DataTemplate)

在这种情况下,您的弹出窗口的VM仍然是可测试的,并且可以接受与父级VM的WPF的最小耦合级别,IMO。

相关问题