Tuesday, May 12, 2009

MVVM Communication among ViewModels

When a new person enters into the MVVM world ,the first doubt in his mind would be ‘How can I achieve messaging among View-Models ? ’or ‘How to notify other ViewModels about a change or operation in one ViewModel ?’ For example if we take a scenario of CRUD database operations there should be notifications passing through on each operation like creation,deletion etc...Otherwise the listing ViewModel will not be up to date.

When the same view-model communication came in to my mind, the possible solutions I got are

  1. Events : Raising events on operations so that subscribed view models will get notification.
    1. Data access layer / Data repository / Data provider  owns events
    2. View models own events.
  2. Mediator pattern : A centralized place where the subscriptions or handlers are stored against messages.

1.Events

This is the common solution found in most of the MVVM implementations.This is very easy to implement too.After each operation an event will get fired and the subscribed viewmodels will update themselves according to that.When we came to implement this method ,the common question would be where we should write these events.There are 2 places where we can write these events.

Events at data layer

The sample contained in the Josh Smith’s article uses this method.Events are written in the data layer and will be fired as soon the operation completed successfully. For more details see the CustomerAdded event in the file CustomerRepository.cs

Pros : All the events reside at a single place.So easy to maintain.ViewModels will contain only data bindable properties and commands.

Cons : If they data layer is done by some other developer who is in different location and doesn’t care about the MVVM this fails.If the project is just to upgrade the UI of an existing application to WPF, we can’t expect the existing data layer with these type of events.

Events at ViewModel level

Here the events are written in the view models.Whenever an operation finishes or a view model wants to notify other viewmodels about something, it will raise an event which in turn ,captured by other view models and they can process according to that.

In the attached sample showing the editing customer view is done by that method.The AllCustomersViewModel has got a new event called EditCustomer which is fired when ever the user clicks on the edit command.ie When we click on the Edit link in the AllCustomersView the event EditCusomer will get fired.Thus MainViewModel receives the notification since it has subscribed to that event and it shows the CustomerView with the selected customer.

I think there is no need to explain the pros and cons as it is reverse of the above.

2.Mediator pattern

This is a well known pattern.For more details about the pattern see these posts

MVVM Mediator Pattern

[MVVM + Mediator + ACB = cool WPF App] – Intro « C# Disciples

In the attached sample you can see the ViewModelMessages.CustomerDeleted message is dispatched  after the deletion in the method CustomerViewmodel.Delete().This is captured by the AllCustomersViewmodel and it updates its collection to update the view.

Sample

The sample attached here is taken from the famous MVVM article by Josh Smith.Thanks Josh.I modified that sample to show these notification mechanisms.It contains the implementation of all these messaging techniques mentioned above.Another change I did is creating separate projects for view,view-model,model,MVVM etc…to easily understand the separation of model and view.

The sample can be downloaded from here.

4 comments:

  1. Great work! Thanks a lot! Simple and clear as it should be for MVVM begginers.

    ReplyDelete
  2. Only one word:
    Exactly!!!

    ReplyDelete
  3. Is it ok to call DemoApp.Settings.Strings.xx in CustomerViewModelTests? I'm thinking of loose coupling... Regards Jamie.

    ReplyDelete
  4. Same thing with Mediator... aren't the viewmodels coupled to Mediator? Regards Jamie.

    ReplyDelete