用MVVM处理WPF中的对话框[英] Handling Dialogs in WPF with MVVM

本文是小编为大家收集整理的关于用MVVM处理WPF中的对话框的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在WPF的MVVM模式中,处理对话框是更复杂的操作之一.由于您的视图模型对视图一无所知,对话框通信可能很有趣.我可以公开一个ICommand,当视图调用时,就会出现对话框.

有人知道处理对话结果的好方法吗?我说的是Windows对话框,例如MessageBox.

我们这样做的方法之一是在ViewModel上有一个事件,该视图将在需要对话框时订阅.

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

这还可以,但这意味着视图需要代码,这是我想远离的.

推荐答案

我建议放弃1990年的模态对话框,而是将控件作为覆盖(帆布+绝对定位)实现,可见性与VM中的布尔相关.靠近AJAX类型控件.

这非常有用:

<BooleanToVisibilityConverter x:Key="booltoVis" />

如:

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

这是我将其作为用户控件实现的方式.单击" X"在后面的USERCONTROL代码中的一行中关闭控件. (由于我在.exe和dll中的ViewModels中有自己的看法,所以我对操纵UI的代码并不感到难过.)

 WPF对话框

其他推荐答案

编辑:超过10年后,我可以说使用调解人或任何其他消息模式在很多层面上都是一个非常坏的主意.不要这样做,只需在视图模型中实现杰弗里的答案或注入的idialogservice.


您应该为此使用调解人. 调解器是一种常见的设计模式,在其某些实现中也称为Messenger . 这是类型寄存器/通知的范式,并启用您的ViewModel和视图通过低耦合的消息传递MeCanism进行通信.

您应该检查Google WPF门徒组,然后搜索调解人. 您会对答案感到非常满意...

您可以从此开始:

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

享受!

编辑:您可以在此处看到MVVM Light工具包的答案:

其他推荐答案

一个好的MVVM对话框应:

  1. 仅用XAML声明.
  2. 从数据框中获取所有行为.

不幸的是,WPF无法提供这些功能.显示对话框需要对ShowDialog()的代码呼叫.支持对话框的窗口类不能在XAML中声明,因此它不能轻易地数据库到DataContext.

为了解决这个问题,我编写了一个XAML存根控制,该控制位于逻辑树中,并将数据指标传递到Window,并显示和隐藏对话框.您可以在这里找到它: http://www.codeproject.com/kb/kb/wpf/xamldialog.aspx

这实际上只是使用,并且不需要对视图模型的任何奇怪的更改,也不需要事件或消息.基本电话看起来像这样:

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

您可能想添加设置Showing的样式.我在文章中解释了这一点.我希望这对您有帮助.

本文地址:https://www.itbaoku.cn/post/627455.html

问题描述

In the MVVM pattern for WPF, handling dialogs is one of the more complex operations. As your view model does not know anything about the view, dialog communication can be interesting. I can expose an ICommand that when the view invokes it, a dialog can appear.

Does anyone know of a good way to handle results from dialogs? I am speaking about windows dialogs such as MessageBox.

One of the ways we did this was have an event on the viewmodel that the view would subscribe to when a dialog was required.

public event EventHandler<MyDeleteArgs> RequiresDeleteDialog;

This is OK, but it means that the view requires code which is something I would like to stay away from.

推荐答案

I suggest forgoing the 1990's modal dialogs and instead implementing a control as an overlay (canvas+absolute positioning) with visibility tied to a boolean back in the VM. Closer to an ajax type control.

This is very useful:

<BooleanToVisibilityConverter x:Key="booltoVis" />

as in:

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

Here's how I have one implemented as a user control. Clicking on the 'x' closes the control in a line of code in the usercontrol's code behind. (Since I have my Views in an .exe and ViewModels in a dll, I don't feel bad about code that manipulates UI.)

Wpf dialog

其他推荐答案

EDIT: More than 10 years after, I can tell that using a Mediator or any other messaging pattern is a really bad idea at so many levels. Don't do it, just implement Jeffrey's answer or a IDialogService injected in your view model.


You should use a mediator for this. Mediator is a common design pattern also known as Messenger in some of its implementations. It's a paradigm of type Register/Notify and enables your ViewModel and Views to communicate through a low-coupled messaging mecanism.

You should check out the google WPF Disciples group, and just search for Mediator. You will be much happy with the answers...

You can however start with this:

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

Enjoy !

Edit: you can see the answer to this problem with the MVVM Light Toolkit here:

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

其他推荐答案

A good MVVM dialog should:

  1. Be declared with only XAML.
  2. Get all of it's behavior from databinding.

Unfortunately, WPF doesn't provide these features. Showing a dialog requires a code-behind call to ShowDialog(). The Window class, which supports dialogs, can't be declared in XAML so it can't easily be databound to the DataContext.

To solve this, I wrote a XAML stub control that sits in the logical tree and relays databinding to a Window and handles showing and hiding the dialog. You can find it here: http://www.codeproject.com/KB/WPF/XAMLDialog.aspx

It's really simply to use and doesn't require any strange changes to your ViewModel and doesn't require events or messages. The basic call looks like this:

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

You probably want to add a style that sets Showing. I explain it in my article. I hope this helps you.