views:

919

answers:

3

hi all ,

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.

+7  A: 

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.

Brian Genisio
+1  A: 

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

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

// in control with button

App.MessageBus.GetEvent().Publish(SimpleObject);

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

App.MessageBus.GetEvent().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.

babernethy
+1  A: 

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.

PL
I agree that it's better to start simple and then introduce complexity as it's needed. It's important though to remember the different patterns and techniques out there though so that if you run into a limitation with your simple implementation you have a plan for action to move to an alternative pattern. I tend to comment my code accordingly to help make it obvious where certain design decisions were made and may change.
jpierson