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

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

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

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

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


当前回答

编辑:10多年后,我可以看出使用Mediator或任何其他消息传递模式在很多层面上都是一个非常糟糕的主意。不要这样做,只需实现Jeffrey的答案或在视图模型中注入一个IDialogService即可。


你应该找个中间人。 Mediator是一种常见的设计模式,在某些实现中也称为Messenger。 它是一种Register/Notify类型的范例,允许ViewModel和Views通过低耦合消息传递机制进行通信。

你应该看看谷歌WPF门徒组,然后搜索调解员。 你会很高兴得到答案的……

但是你可以这样开始:

http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/

享受吧!

编辑:你可以看到这个问题的答案与MVVM轻工具包在这里:

http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId=209338

其他回答

在询问任务或对话框的视图模型应该是什么样子时,我也在思考一个类似的问题。

我目前的解决方案是这样的:

public class SelectionTaskModel<TChoosable> : ViewModel
    where TChoosable : ViewModel
{
    public SelectionTaskModel(ICollection<TChoosable> choices);
    public ReadOnlyCollection<TChoosable> Choices { get; }
    public void Choose(TChoosable choosen);
    public void Abort();
}

当视图模型决定需要用户输入时,它会调出一个SelectionTaskModel实例,其中包含用户可能的选择。基础设施负责调出相应的视图,该视图在适当的时候根据用户的选择调用Choose()函数。

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

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

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

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

我也遇到过同样的问题。我已经提出了一种在视图和视图模型之间进行交互的方法。您可以发起从ViewModel向View发送消息,告诉它显示一个消息框,然后它将报告返回结果。然后ViewModel可以响应从View返回的结果。

我在博客中对此进行了说明:

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

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

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