在WPF的MVVM模式中,处理对话框是比较复杂的操作之一。由于视图模型不知道视图的任何信息,因此对话框通信可能会很有趣。我可以公开一个ICommand,当视图调用它时,就会出现一个对话框。

有人知道处理对话框结果的好方法吗?我说的是windows对话框,比如MessageBox。

其中一种方法是在视图模型上设置一个事件,当需要对话框时,视图会订阅该事件。

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

这是可以的,但这意味着视图需要代码,这是我想要避免的。


当前回答

关于这个主题,我已经写了一篇相当全面的文章,还为MVVM对话框开发了一个弹出式库。严格遵守MVVM不仅是可能的,而且在正确实现时非常干净,而且它可以很容易地扩展到自己不遵守MVVM的第三方库:

https://www.codeproject.com/Articles/820324/Implementing-Dialog-Boxes-in-MVVM

其他回答

一个好的MVVM对话框应该:

仅用XAML声明。 从数据绑定中获取它的所有行为。

不幸的是,WPF不提供这些特性。显示对话框需要对ShowDialog()进行代码隐藏调用。支持对话框的Window类不能在XAML中声明,因此它不能轻易地绑定到DataContext。

为了解决这个问题,我写了一个XAML存根控件,它位于逻辑树中,将数据绑定传递给一个Window,并处理显示和隐藏对话框的问题。你可以在这里找到它:http://www.codeproject.com/KB/WPF/XAMLDialog.aspx

它使用起来非常简单,不需要对ViewModel进行任何奇怪的更改,也不需要事件或消息。基本调用如下所示:

<dialog:Dialog Content="{Binding Path=DialogViewModel}" Showing="True" />

您可能希望添加一个设置显示的样式。我在我的文章中解释过。我希望这对你有所帮助。

最简单的方法:使用HanumanInstitute。MvvmDialogs图书馆

如果您遵循文档,您可以像这样漂亮地使用它,并与UI完全解耦

var presetName = await dialogService.ShowSavePresetViewAsync(this);

我认为处理对话框应该是视图的责任,视图需要有代码来支持这一点。

如果你改变ViewModel - View交互来处理对话框,那么ViewModel依赖于该实现。处理这个问题最简单的方法是让视图负责执行任务。如果这意味着显示一个对话框,那么很好,但也可以是状态栏中的状态消息等。

我的观点是,MVVM模式的全部观点是将业务逻辑从GUI中分离出来,因此您不应该在业务层(ViewModel)中混合GUI逻辑(以显示对话框)。

关于这个主题,我已经写了一篇相当全面的文章,还为MVVM对话框开发了一个弹出式库。严格遵守MVVM不仅是可能的,而且在正确实现时非常干净,而且它可以很容易地扩展到自己不遵守MVVM的第三方库:

https://www.codeproject.com/Articles/820324/Implementing-Dialog-Boxes-in-MVVM

我遇到了同样的情况,并将MessageBox包装成一个设计器不可见控件。详情在我的博客里

http://geekswithblogs.net/mukapu/archive/2010/03/12/user-prompts-messagebox-with-mvvm.aspx

同样可以扩展到任何模态对话框,文件浏览控件等。