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

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

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

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

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


当前回答

为什么不只是在VM中引发一个事件,然后在视图中订阅该事件呢?这将保持应用程序逻辑和视图分离,并且仍然允许您为对话框使用子窗口。

其他回答

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

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

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

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

我建议放弃20世纪90年代的模态对话框,而是实现一个覆盖控件(画布+绝对定位),可见性绑定到虚拟机中的布尔值。更接近ajax类型控件。

这非常有用:

<BooleanToVisibilityConverter x:Key="booltoVis" />

如:

<my:ErrorControl Visibility="{Binding Path=ThereWasAnError, Mode=TwoWay, Converter={StaticResource booltoVis}, UpdateSourceTrigger=PropertyChanged}"/>

下面是我如何实现一个用户控件。单击“x”关闭后面用户控件代码中的一行代码中的控件。(因为我有我的视图在一个。exe和ViewModels在一个dll,我不觉得代码操纵UI。)

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

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

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

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