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.)
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:
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.
I use this approach for dialogs with MVVM.
All I have to do now is call the following from my view model.
var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With