Lucas
Lucas

Reputation: 3500

How to communicate between two MVVM pairs?

I have a little app with a overview of some items (entries). The title of the entry at the list in the overview is a property of the entry. When I click an entry a kind of tab should open where I can edit the entry. When I edit and save the entry, the overview tab should update the next time.

Here a mockup for better understanding.

App is based on MVVM pattern. Each View has a ViewModel as DataContext. Each ViewModel uses a Model and each Model has a Database.
The overview tab have it's own View, ViewModel and Model (pair). Also the tabs. Each tab for entries use the same pair (singleton instance). Only a few bindings are updated If a other tab is selected.

My question is how to communicate between the tabs.

I have two approaches

But I dont' feel well with these approaches.
Should I communicate between Models or between ViewModels? Or is this the wrong way?

UPDATE

I really appreciate all of your answers. In my opinion none of them are wrong or right. I think it's a matter of taste which solution is right for one is. I really like the EventAggregator pattern. Here is a nice video from Karl Shifflett about the implementation of the EventAggregator pattern in PRISM. But it also explains the pattern itself.

@Thomas In my opinion it is a bad solution to do this in one ViewModel. ViewModels have to be separated. MVVM based on Separation of Concerns.

Upvotes: 2

Views: 1154

Answers (4)

Tae-Sung Shin
Tae-Sung Shin

Reputation: 20620

For me, it's usually a bad sign when I have to program for communication between view models. Sometimes, you have to make communication between view and view model, but the need for connecting two view models seems to always result in combining two view models if possible.

With your mockup, I felt the same bad feeling. Why do you have to have separate view models for tabs in first place? In your case, views can be separate but I don't see any benefit from separating view models. Thus, combining the two view models into one is my recommendation.

Upvotes: 2

Rob Perkins
Rob Perkins

Reputation: 3130

You should communicate between ViewModels, if the functionality is related to formatting Model data for display. If your are communicating data from one Model to another, then communicate between Models.

Here is a concrete example: The Microsoft.Practices.Prism namespace, which you can access with NuGet right in Visual Studio, includes a class called CompositePresentationEvent<T>, along with an EventAggregator class which does the actual communicating.

Someplace common to your entire application (I chose App.xaml.vb, but it can be any publicly scoped code file, and it works as well for C# as for VB), you define events by inheriting from that class, and supplying the type T which corresponds to the data you're sending. For example, if you want to send a message that contains a simple string, then declare:

Public Class MyEvent: Inherits CompositePresentationEvent(Of String) : End Class

In your Application class, you define an event aggregator:

Public Shared ReadOnly AppEventAggregator As IEventAggregator = New EventAggregator()

Those two items together give you the means to trade events between any two objects in your application.

This gives your entire application access to an event called MyEvent. Wherever you want to send the MyEvent message, you call its shared Publish(String) method:

Application.AppEventAggregator.GetEvent(Of MyEvent).Publish("This is my event message")

Then, to receive the event, you implement a private read-only field in the class where the event should land, something like:

Private ReadOnly MyEventToken As SubscriptionToken =
Application.AppEventAggregator.GetEvent(Of MyEvent).Subscribe(Sub(eventMessage) DoSomethingWithTheString(EventMessage))

...where DoSomethingWithTheString(eventMessage As String) would be where you process your event.

There's (a lot) more to Prism, of course, but never a need to use more of it than you need, and, as others have pointed out, lots of other MVVM frameworks with similar approaches to solving the same problem.

Upvotes: 2

Wiktor Zychla
Wiktor Zychla

Reputation: 48314

Mediator is a step in a right direction but an Event Aggregator is much more flexible. You can find dozen of implementations. For example, Prism has a ready-to-use implementation.

Communication is between ViewModels. ViewModels register themselves for notifications in the Aggregator and raise notifications on the Aggregator.

Upvotes: 2

Venson
Venson

Reputation: 1870

Maybe this Post is interesting for you, it Describe a Pattern for a Communication on Type basis. It allows you to Communicate between everything you want, without dependences between them

Upvotes: 1

Related Questions