Communication between view models in Windows 8 MVVM pattern

Post date: Sep 12, 2014 12:26:02 PM

Window 8 mobile application recommends MVVM pattern for Win8 application development. So its each win 8 application may have more than one model, there is possibility where one model has to listen some event from another model.

Below I have discussed the problem I have faced in my project.

1. I have main screen called (ProductList) and it's data context is ProductViewModel.  It has one button called  "Add Product", by click this button user will be shown with "Add Product Popover " (User Control)  will be screen to pick the books from it.

2. "Add Product" is a user control which has separate "DataContext" called "BookViewModel" . It has 2 buttons as "Cancel" and "Done". 

These button actions is handled in "BookViewModel" and also some more actions needs to be done in Parent Model. (ProductViewModel)

Which means there is a communication between BookViewModel& ProductViewModel. 

To achieve this I deiced to go for "PRISM" framework.

1. Download prism framework "Microsoft.Practices.Prism.PubSubEvents.dll" from https://www.nuget.org/packages/Prism.PubSubEvents/

2. Add prism reference to your project "Microsoft.Practices.Prism.PubSubEvents.dll"

3. Create some custom class which is used for communication modem.

     class Notifications : PubSubEvent<string>

    {

    }

4. Create  IEventAggregator eventAggregator singleton instance for your project and initialize it.

public sealed class SessionInfo

{

         public  IEventAggregator eventHanlder;

            private SessionInfo (){


            }

    private static SessionInfo _instance = null;

    public static SessionInfo Instance{

get{

lock (lockObj) {

if (_instance == null) {

_instance = new SessionInfo ();

                        _instance.eventHanlder= new EventAggregator();

}

}

return _instance;

}

}

        }

5. Go to Popover model (BookViewModel) button events handling and below codes in it.Now it has been published.

In BookViewModel.cs:

     //For cancel button click

    public void OnBtnCancel()

   {

            SessionInfo.Instance.eventHanlder.GetEvent<Notification>().Publish("Cancel");

        

   }

 //For cancel button click

    public void OnBtnDone()

   {

            SessionInfo.Instance.eventHanlder.GetEvent<Notifications>().Publish("Done");

        

   }

6. These event aggregator has to be subscribe where it is needed. So add below code on your Parent View model (ProductViewModel)

ProductViewModel.cs

  public class ProductViewModel

 {

            public ProductViewModel()

            {

                SessionInfo.Instance.eventHanlder.GetEvent<Notifications>().Subscribe(OnReceivedNotification);

            

            }

        //Handling the notification 

    public void OnReceivedNotification(string notificationName)

        {

            Debug.WriteLine("Received Notification name :" + notificationName);

            switch (notificationName)

            { 

                case "Done":

                    this.IsOpenAddResourcePopover = false;

                    break;

                case "Cancel":

                    this.IsOpenAddResourcePopover = false;

                    break;

            }

        }

  }