Communication between ViewModels with MVVM

Communication between ViewModels can be tricky at first glance, but there are some easy frameworks and patterns that can help you out.

For example, lets say you had a ShellViewModel that controlled your entire application, and it has an Exit command. Now lets say one of the sub-view-models in the application would like to call this exit command.

The easiest way is through a Relative Binding to the Window’s DataContext.ExitCommand.

<Button Command="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type Window},
    Path=DataContext.ExitCommand}}

Of course, this only works well if you can find the control containing the command you want through a binding.

Enter the Event System

Another way is through a loosely coupled event system. I would recommend either MVVM Light’s Messenger or Microsoft Prism’s EventAggregator. You could always build your own event system as well if you really wanted to.

Both event systems makes me think of a paging system. Any ViewModel can broadcast a message, and any ViewModel can subscribe to receive broadcasted messages. Messages are often packaged into different types, so a ViewModel can subscribe to only listen for specific message types such as CloseApplicationMessages.

This kind of loosely coupled event system is ideal for MVVM because the ViewModels don’t need to know about each other to be able to do their job.

Using either of these systems, your ViewModel that handles the event would subscribe to receive a specific message type. It would tell the event system that if a message of type X is broadcasted, send it to a specified delegate method. The ViewModel that wishes to raise the event simply has to broadcast the message and include any parameters needed in the body of the message.

Example using Prism’s EventAggregator

// Subscribe
eventAggregator.GetEvent<CloseAppliactionMessage>().Subscribe(ExitMethod);

// Broadcast
eventAggregator.GetEvent<CloseAppliactionMessage>().Publish();

(I also have some code posted here which simplifies PRISM’s EventAggregator for smaller applications)

Example using MVVM Light’s Messenger

//Subscribe
Messenger.Default.Register<CloseAppliactionMessage>(ExitMethod);

// Broadcast
Messenger.Default.Send<CloseAppliactionMessage>()

7 Responses to Communication between ViewModels with MVVM

  1. Musaab says:

    I’m using MVVM Light Messenger , I don’t know about the others but this one can send and receive anything , you can’t imagine how much I was happy when I was able to send and receive a message of type ObservableCollection

    • Rachel says:

      I used to send objects such as collections or integers directly through the event system too, but as my applications got bigger, I found it was easier to understand my code when I packaged the event parameters into a Message class and used that class with the event system. Not only did it make my application easier to manage and understand, it also allowed me to pass around multiple parameters with my events.

  2. Aaron B says:

    Excellent post. Well written and very informative. Thank you for taking the time to share. I really like the idea of using a messenger class. I may have to explore that avenue a little more. :)

  3. Keith Nicholson says:

    In what methods are you placing the MVVM Light Messenger calls? My sender has it in a private method responding to a RelayCommand and the receiver is in the constructor of another view model.

    • Rachel says:

      Hi Keith,

      Typically hooking up the receiver occurs in the Constructor or initialization code so it’s easy for me to find and keep track of, while broadcasting a message happens anywhere in the code that it needs to happen.

  4. Donnie K says:

    Hello, I am just trying to make the transition from WinForms to WPF and I am a vb.net developer. Do you have any examples of communicating between ViewModels without the use of a framework? I am working on my first app and would like to have a StatusBar that is “globally” accessible from all ViewModels. This is posing quite a problem! My plan is to create a ViewModel for each View and have the StatusBar updated from each View. Any help would be greatly appreciated!

    • Rachel says:

      Hi Donnie,

      I’m sorry, don’t have any example messaging systems that don’t use a framework. You could use a single StatusBarViewModel somewhere, such as a singleton, or inject/pass a StatusBarViewModel to each of your viewmodels from your parent ViewModel.

      Don’t forget that with MVVM, your ViewModels are your application, not your Views, so your shared StatusBar object should be a ViewModel or Model, not a UserControl.

      I do have an example of a simplified EventAggregator that works with the PRISM library that you might find useful, or if you’re new to WPF you may want to check out my article about transitioning from Winforms to WPF.

      Good Luck,
      Rachel

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 96 other followers

%d bloggers like this: