Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

silverlight - communicate between 2 view models in MVVM using commands

i am working on MVVM and using commanding in silverlight(DelegateEvent and ICommand)

I want something like this ,(say) i have 2 usercontrols , parent and child .

Parent is hosting the child , both have thier own viewmodels .

On parent i have a button and it executes a simple command , on execute of that command i want to update text in the child control's textbox . also we should be able to change something in child which can propagate to the parent .

Is events the best answer for this or i can have commands to update child/notify parent in some way.

like image 994
AB. Avatar asked Nov 20 '09 14:11

AB.


3 Answers

There are several ways to go about this.

First, it is completely appropriate to have ViewModels that are composed of other ViewModels, as long as you are OK with them being coupled in that way. When you do that, they can just talk to each other using regular method calls.

Next, you can decouple a bit and use events. Nothing wrong with that. There is still an Observer -> Observable coupling, but they are less dependent upon each other.

Next, you can completely decouple and use something like an EventAggregator (Prism has a good one you can use). Shoot a Publish a message. The other subscribes. They don't know about each other at all.

I have used commands for this as well... but for ViewModel to ViewModel communication, I find this to be a bit awkward.

like image 55
Brian Genisio Avatar answered Oct 02 '22 11:10

Brian Genisio


You should probably start with most obvious implementation where parent viewmodel simply holds a reference to a child viewmodel, and child viewmodel holds a reference to a parent viewmodel. Then when a command is executed on parent viewmodel it simply sets a value on a child viewmodel to which textbox is bound to.

Adding a layer of abstraction between parent and child (e.g. events) adds a level of complexity and as a result it should be justified. If the value this indirection provides is higher than the cost of increased complexity of the code (e.g. it's now less clear what happens when command on a parent is executed, you will have to solve a problem how child gets subscribed to parent's event without obtaining the actual reference to it and vice-versa, adding additional dependencies between parent a child will require adding additional events, which pollutes the actual logic with all the plumbing, etc.) then certainly events (or something like PropertyObserver) might be a next logic step.

like image 36
PL. Avatar answered Oct 02 '22 13:10

PL.


This seems like an ideal situation for using an EventAggregator like the one in the Composite Application Guidance / Prism.

In this model, you can set up a MessageBus in the root of the application (or other common area).

// in App.xaml.cs

public static IEventAggregator MessageBus = new EventAggregator();

Then set up a common Messages library

// in Messages.cs

    public class SimpleCommand: CompositePresentationEvent<SimpleObject> { }

Where SimpleObject is a class or variable that contains all the info necessary to process this event.

// in control with button

    App.MessageBus.GetEvent<Messages.SimpleCommand>().Publish(SimpleObject);

// anywhere in your app that you "care" about this 

    App.MessageBus.GetEvent<Messages.SimpleCommand>().Subscribe(ProcessingMethod);

Where ProcessingMethod is a method that takes a SimpleObject as a parameter.

Then you can spout off messages from anywhere and process them anywhere - across viewmodels, controls, etc. You can even pass MessageBuses between components if you are dynamically loading parts of the app. Works well.

like image 42
babernethy Avatar answered Oct 02 '22 12:10

babernethy