Composite Command or Service

Topics: Prism v4 - WPF 4
May 27, 2011 at 1:45 PM

Hi,

I have this following situtaion,

- I have a base region, containing my toolbar [Say mainRegion]

- There is a child region in this [say ChildRegion]. This region contains multiple Child Items [different views with View Models]

 

I have close button on my toolbar [on MainRegion], on click of that, I want to close all the child items on my ChildRegion.

Now the point is, I am little confused about which mode of communication to use,

1) Composite Command - Have a CloseAll command. Which would raise mutliple Close Commands on all the child items.

2) Service layer?

Any pointers/links highly appreciated.

Thanks,

Indro

Developer
May 27, 2011 at 1:57 PM

Hi Indro,

Based on my understanding of your scenario, using composite commands should be most suitable to fulfill your requirement.

Although you could achieve the same results using a service layer, composite commands are designed to fulfill scenarios similar to yours. You can find more information about it in the Communication Chapter as well as the Commanding QuickStart.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

May 27, 2011 at 3:48 PM

Hello Guido,

Thanks for the reply.

I have one more scenario:)..

I have the same toolbar (with different buttons, like zoom etc.) As a part of childregion, I have multiple child items (of same type).

Now when I use Zoom button, I want only my active view (and its content) to get zoomed...

What should be the communication strategy here?I have considered two approaches here,

1. Using a Composite Command (like ZoomActiveCommand), which will have child ZoomCommands defined in each of the ViewModel (corresponding to each child views). I will zoom the view based on the IsActive flag (from IActiveAware interface implementation in VM)

2. Use Event aggragator in execute handler of the Command attached to the Toolbar button. This event will be subscribed on my different ViewModel (corresponding to each child views). In subscriber, I will use same strategy as (1) [using IsActive flag] to determine my active views and perform zoom.

 

Helps appreciated.

Regards,

Indro

Developer
May 27, 2011 at 4:15 PM

Hi Indro,

In that case, I would recommend to use the event aggregator, as I believe it would be more comfortable. You could use a filter in the subscription, which could check if the view is active before executing the handler for that event subscription.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

May 27, 2011 at 4:28 PM

Hello Guido,

Thanks for the suggestion. This works out for me perfectly well.

Thanks again.

Indro

May 31, 2011 at 7:47 AM

Hello Guido,

I am using ZoomAllCommand bound to my toolbar zoom button, which triggers ZoomCommands on each of the child views (checks if it is active) and exeutes.

Now at this point I am wondering is using composite command a mistake(?) Because I need to access my View (and some custom control on it) and call some method!, which is not possible from ViewModel!!

 Any ideas?

Regards,

Indro

Developer
May 31, 2011 at 2:33 PM
Edited May 31, 2011 at 2:35 PM

Hi Indro,

In that case, you could use Composite Commands, but in the handler for your command you could use other mechanisms for communicating between loosely coupled components, such as firing an event with the Event Aggregator, or calling a method on a Shared Service, so as to communicate to your view that it must zoom its content.

You can read more about this in the communication chapter of the Prism MSDN documentation.

Another possibility that I could think of, if you don't want to use the aforementioned mechanisms, would be to have your view implement an IZoom interface, which exposes a Zoom method (or something similar), and make your view model hold a reference to it. The handler of your composite command should therefore call the Zoom method on your view, but it would still have an abstraction over the view it holds (as the only thing it knows about it is that it implements the IZoom interface).

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Feb 18, 2012 at 8:53 AM

hi,

i'm new at developing prism app but i'm also building an app using prism. I don't use regions at the moment though. I had a similar problem. I wanted to implement a save and save all command. I implemented these by using CompositeCommands. I think your situation is the same and CompositeCommands worked great for me (although with a little costom code since i'm not using regions yet). here is what i did.

both commands are custom CompositeCommands. the save all command doesn't use command monitoring, only the save command does. In my app i want to disable saving if the current document isn't dirty. This doesn't work well with the default CompositeCommand behavior which can only execute the command if all commands registered with it can execute. To fix this i derived from CompositeCommand and i overrode the CanExecute() method.

Next i exposed the commands in my shell view model. In my child view models i registered each view model save command with both the save and save all CompositeCommands. The only problem that remained now was to find a way to make the save command behave properly. Since i'm not using regions i have to implement the IActiveAware interface in the child view models. When the IsActive property on a particular child view model changes i also change the corresponding save command IsActive property. Now, whenever the current document changes i set IsActive to false on the previous one and set IsActive to true on the new one.

This solved my problems. There is no need for event aggregators in this scenario. I hope this helps.