我有一个使用mvvm模式的WPF应用程序,我需要从我的主视图模型中显示一个对话框。
我有一个带有视图模型的辅助视图,我认为我有两个选项来创建对话框。
选项1
在主视图模型中,我可以执行以下操作:
选项2
在主视图模型中:
在对话框的视图模型的构造函数中:
我知道在MVVM中,视图模型必须对视图一无所知,但在第二个选项中,实际上,视图模型没有任何链接到视图的属性,只是在构造函数中创建了一个显示在最终状态下,视图模型对视图一无所知。
但是,我认为主视图中的代码更清晰,因为我只需要创建视图模型,只需要一行代码,而不是需要4行的选项1(创建视图,创建视图)模型,将视图模型分配给视图并显示对话框。
如果我想遵循mvvm模式,我认为第二种选择并不是一个坏主意我错了吗?
答案 0 :(得分:1)
在大多数情况下,有几种方法可以实现解决方案。
对于具有多个对话框,窗口或页面的较大应用程序,最佳方法是服务,例如IDialogHandler
。通过c_tor给VM。您可以在此post中找到一个示例
最大的优点是解耦使VM易于测试,因为它们没有对视图的引用。
对于较小的应用程序,假设有2个或3个不同的对话框,以下方法也是正确的。
public class DialogView : Window
{
// a method to create easily a dialog
public static void ShowDialog(DialogViewModelBase dialogVm)
{
var dialog = new DialogView { DataContext = dialogVm };
dialog.ShowDialog(); // pls note, that this will create a modal dialog
}
}
因此可以从任何地方调用DialogView.ShowDialog(...)
。但是VM在这里有对视图的引用
这类似于你的 OPTION 1 ,好的步骤顺序不一样,但它足够接近。
答案 1 :(得分:1)
我为{wpf
中的对话做thisvar result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
... do anything with the dialog result...
答案 2 :(得分:1)
无论你选择哪种方式,都有一个麻烦
坦率地说,它不仅涉及对话而且涉及所有窗口。在MVVM中,这可能会成为一种真正的痛苦。至少对我们的团队来说,当我们同时使用WinForms和WPF时。
大多数开发人员忘记了窗户的亲子关系
关于对话框窗口,这会导致一些不好的用户界面:对话框可能会出现在主窗口下面,因为显示的对话框没有响应。 (你可以很容易地重新制作它)。
因此,在MVVM中,您需要以某种方式设置父级。而这里重要的是View不是一个窗口。
我们这是怎么做的。
我们首先采用ViewModel方法。但我们不会在VM中注入View。我们传递IViewService,它对View实例化,父子关系和某些事件的侦听都是可信的
想想当用户点击右上角的交叉时,虚拟机如何阻止其关闭视图。