views:

937

answers:

4

How do I go about having two view models communicate with one another using MVVM Light. I know how to use the messenger class and register etc.. Here is my Scenario

A Settings View ---> a Settings View Model 
                                  .
                                  .
                                  .

A MainPage View ---> A MainPage ViewModel

If something changes in the Settings View it will Message back to the Settings View Model. So then I want the Settings View Model to communicate to the MainPage View Model about what changed. THe MainPage ViewModel will then tell the View.

+8  A: 

A common pattern for this style of problem is Mediator (a class that both view models reference and can be used to pass messages between the two).

The pattern I prefer is the Event Aggregator, an example can be found in the Prism framework. In this pattern different view models subscribe to events from the aggregator and others publish events.

Hope this helps

Nigel Sampson
This. The Event Aggregator is a nice and clean way of doing decoupled communication. The only thing I dislike about it is the need to place the event definitions in a common location, but that's just a minor quibble.
JerKimball
+1  A: 

I second Nigel's suggestion of using the Mediator, take a look at Josh Smith's blog and his implementation of this:

http://joshsmithonwpf.wordpress.com/?s=mediator

At the bottom you can download the Mediator Prototype and Demo, just remember to rename it from .doc to a .zip.

Hope this helps...

Richard
+1  A: 

One thing you can try out is try to implement Dependency Inversion. Define an interface with some actions/contracts. Implement that interface on MainviewModel. Pass that interface as member variable to SettingsViewModel. So whenever settings view model has to notify something to main, it will use that interface. And additionally, other view models can use same strategy.

public interface IMessenger
    {
      void NotifyAction();
    }

    public class MainViewModel:InotifyProprtyChanged,IMessenger
    {
     public void NotifyAction()
    {
    }
    }

    public class SettingsViewModel:INotifyPropertyChanged
    {
      public IMessenger Messenger{get;set;}

      public void SomeCommandExecutor()
      {
        if(Messenger!=null)
         {
           Messenger.NotifyAction();    
         }

      }
    }


Rakesh Gunijan
A: 

Rakesh, I like where your going with this can you exand a little? In your example can you include the part where you "Pass that interface as member variable to SettingsViewModel."

If you are going to construct SettingsViewModel in MainViewModel methods, you just have to do SettingsViewModel svm = new SettingsViewModel(){Messenger = this};Or you can map MainViewModel and SettingsViewModel at place where SettingsViewModel is constructed. This scenario will occur when SettingsViewModel is constructed outside MainViewModelIn that case you will be having acces to both SettingViewModel instance and MainViewModel instance at som other place, and it will do the mapping In design principle world, they call it as Mediator pattern...Wht do u say?
Rakesh Gunijan