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;
}
}
}