WPF MVVM and Showing Dialogs

Developing a WPF/Silverlight application using the MVVM (Model-View-ViewModel) pattern is a real challenge. But you know that using this pattern you write low-coupled and fully testable code (I hope). As MVVM says, the View can contain only XAML declarations. That is, no code-behind is present in your .xaml.cs file.

The Problem

Everythins is so cool till now. But how do you work with dialogs in your project? A dialog should have an owner and can be either modal or non-modal. It should accept some input data and also return a result.

The Solution

There are a few solutions for this problem. I will show you the most popular but you have the final choice.

Using a Mediator

Mediator is a concept introduced by the WPF Disciples. It’s a paradigm of type Register/Notify and enables your ViewModel and Views to communicate through a low-coupled messaging mecanism. Josh Smith has written a great article on that.

Using a Dialog Control

There is a statement that 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.

The solution is to use a XAML stub control that is part of the logical tree and relays databinding to a Window. It also handles showing and hiding the dialog. It’s really simply to use and doesn’t require any strange changes to your ViewModel.

Using a Service

This is my favorite one! It’s easy to implement and easy to replace if necessary. In this solution you create a service, which creates your dialog and returns what you need.

In the constructor of your ViewModel pass a reference to your service implementation. When you need to perform an action, you just call your service’s method and wait until it returns something. Isn’t is cool? You can always pass an implementation that calls a real web service or something like that. You are not limitted to using dialogs.

But, something is missing. How should you speficy the owner of the created window? You need to access it some way but the ViewModel don’t know which View is using it. Well, there a trick to solve that. You create a class which contains a declaration of an attached dependency property. All this property does is to register the View in a list. This way you have all active Views in a collection. The next question is how to determine which View you need. Its answer is pretty simple. You relay on that the connection between View and ViewModel is 1:1. As you can see, you pass a reference to the owner ViewModel in the method above. Then you can search the collection of Views and check the DataContext property of each of them.

Read more about this approach at CodeProject.

Additional Resources