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

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

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

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

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


当前回答

Karl Shifflett创建了一个使用服务方法和Prism InteractionRequest方法显示对话框的示例应用程序。

我喜欢这种服务方式——它不太灵活,所以用户不太可能弄坏东西:) 它也与我的应用程序的WinForms部分(MessageBox.Show)一致。 但如果您计划显示许多不同的对话框,那么InteractionRequest是更好的方法。

http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/

其他回答

我目前的解决方案解决了你提到的大部分问题,但它完全从特定于平台的东西中抽象出来,可以重用。 此外,我使用了没有代码隐藏,只与实现ICommand的DelegateCommands绑定。 对话框基本上是一个视图——一个独立的控件,它有自己的ViewModel,它从主屏幕的ViewModel显示,但通过DelagateCommand绑定从UI触发。

查看完整的Silverlight 4解决方案在这里与MVVM和Silverlight 4模态对话框

我在对这个问题的回答中描述了我自己的窗口加载器:

在应用程序中管理多个WPF视图

一个有趣的替代方法是使用控制器来显示视图(对话框)。

WPF应用程序框架(WAF)说明了这是如何工作的。

我知道这是一个老问题,但当我做这个搜索时,我发现了很多相关的问题,但我没有找到一个真正明确的回答。所以我做了我自己的对话框/消息框/popin的实现,我分享它! 我认为这是“MVVM证明”,我试着让它简单和适当,但我是WPF的新手,所以请随意评论,甚至提出拉请求。

https://github.com/Plasma-Paris/Plasma.WpfUtils

你可以这样使用它:

public RelayCommand YesNoMessageBoxCommand { get; private set; }
async void YesNoMessageBox()
{
    var result = await _Service.ShowMessage("This is the content of the message box", "This is the title", System.Windows.MessageBoxButton.YesNo);
    if (result == System.Windows.MessageBoxResult.Yes)
        // [...]
}

或者像这样,如果你想要更复杂的popin:

var result = await _Service.ShowCustomMessageBox(new MyMessageBoxViewModel { /* What you want */ });

它展示了这样的东西:

我认为视图可以有代码来处理来自视图模型的事件。

根据事件/场景的不同,它还可以具有订阅视图模型事件的事件触发器,以及响应中要调用的一个或多个操作。