The Digital Playground Problems, solutions and maybe a few rants

9Aug/100

Using a Mediator Pattern to open Child/Modal Windows in WPF .NET 4 using MVVM

The Problem

If you are using the MVVM pattern, your View knows about your ViewModel, but not the other way around (and of course you have no code in your code-behind files). Imagine if you push a "Create new Customer" button in your View and you want this to open a new window, where you can enter information about the Customer. The button press is bound to a command in your ViewModel, however the ViewModel cannot open any Windows itself and now you are stuck and your boss is angry as hell. You, the living proof that Dilbert is actually a real person, needs to find a solution. Enter the Mediator Pattern, an Implementation of this pattern by Josh Smith, and a sample application and blog, that is hopefully easy to understand, by me (I did not like the sample application in Josh Smiths MVVM Framework, so this is why I wrote my own).

TLDR: Look at the sample application.

The Solution

Basically we are creating a class that enables other classes to listen to broadcasts of the channels they choose to. In this example I am creating a "ViewModelToView" channel, that the View will be listening to. To continue the above "Create New Customer" example, once the button is pressed, your ViewModel broadcasts "Open Window Create New Customer" to the "ViewModelToView" channel. The other ViewModels are not listening to this channel, they could not care less, however the View is listening and opens the "Create New Customer" window. This Window has its own ViewModel and once the Window is closing, the "Create New Customer" ViewModel broadcast its changes to the "ViewModelToViewModel" channel which lets the rest of the ViewModels do what they want with the changes. It also broadcast to the "ViewModelToView" channel in order to tell the View that it should close the "Create New Customer" window again. Lost? Don't be, just follow the below step-by-step Explanation, or download the sample application and see for yourself.

The Resources

The Explanation

Setting it all up

I am using three classes from the MVVM Framework:

  • Messenger.cs
  • ObservableObject.cs
  • RelayCommand.cs (I am actually using the RelayCommand from Josh Smiths MVVM Article because I like it a bit better)

I have created a Visual Studio 2010 solution, with three projects:

  • View (.NET 4 WPF Application)
  • ViewModel (.NET 4 Class Library
  • Common (.NET 4 Class Library)

I have not bothered with the Model, I like my sample applications small and clean. Since your Common Project will contain your Messenger (the Mediator) Class, this needs to be referenced in both your View and your ViewModel. Import the Messenger Class into your Common Library, the RelayCommand Class and ObservableObject Class into your ViewModel.

Create a total of 4 Windows in the View (You already have the MainWindow.xaml and App.xaml, so you need to add 2 more), I called mine WindowA.xaml and WindowB.xaml, and create all three corresponding ViewModels in the ViewModel project. In order to control the Windows you need a Class file in the View Project, I called mine WindowManager.cs. Last but not least, create a class called MediatorMessages in the Common Project.

Now you should have MediatorMessages.cs and Messenger.cs in the Common Project, App.xaml, MainWindow.xaml, WindowA.xaml, WindowB.xaml and WindowManager.cs in the View Project and MainWindowViewModel.cs, WindowAViewModel.cs, WindowBViewModel.cs, ObservableObject.cs and RelayCommand.cs in the ViewModel Project.

The View

The (untested) Alternatives:

To Be Continued 09-08-2010 (or 10-08-2010, it is getting late)...

Please feel free to post any questions, comments or feedback.

8Aug/100

Welcome to my blog

Greetings and welcome to my blog!

This blog is going to be about me and my life, programming and everything in between. I will do a more thorough about page at some point.

Filed under: Personal No Comments