Create own Composite Command

Topics: Prism v4 - WPF 4
Feb 8, 2010 at 2:27 PM

Hi all. In Composite.Presentation library I found only one ready to use command "Click" wich always demonstrated in examples. How can I create my own command for UI controls to events such as TabItem1_Selected or ComboBoxItem_Selected...  Please show how?

Feb 10, 2010 at 10:26 PM

Hi,

Prism provides an out of the box implementation for the attached behavior to hook the click event of a Button with a command in your ViewModel (you can read a deeper explanation here). Take into account that the particular behavior was only meant for Silverlight, as WPF already provided that functionality (currently Silverlight 4 also does).

Some time ago I created a blog post that provides a code snippet to create commands with attached behaviors for other controls and events which might be useful for you. You can read about it here.

Please let me know if this helps.

Damian Schenkelman 
http://blogs.southworks.net/dschenkelman

Feb 24, 2010 at 5:28 AM
Edited Jun 15, 2010 at 6:25 AM

Many thanks. That is, there are 2 ways:

1) We have already written ButtonBaseClickCommandBehavior and CommandBehaviorBase to create commands with attached behaviors. Here is one question. Except static class command_name with DependencyPropertyes and Behavior we must describe at code behind our command: i.e.

public ICommand TabItem2Activated { get; private set; }
this.TabItem2Activated = new DelegateCommand<void>(OnTabItem2ActivatedCommandExecuted);
eventAggregator.GetEvent<MyEvent>().Subscribe(OnTabItem2ActivatedCommandReceived);

But how to hang a few events on the one control and use parametres? What is preferable DelegateCommand or CompositeCommand?

2) Using ICommand interface where we will write executeMethod and canExecuteMethod methods. It easy to describe and bind in xaml:

<Button Command="{Binding SomeCommand}"/>

But what benefits we lose?

Jun 15, 2010 at 6:37 AM

Comrades! Please give some examples of using ICommand with IEventAggregator subscribe and publish service!

Developer
Jun 18, 2010 at 9:03 PM
Edited Jun 20, 2010 at 4:06 AM

Hi,

I’ve created a sample application to show you how to use a DelegateCommand with parameters and the EventAggregator. You can download it from here.

As for your questions,

1) You don’t necessarily have to write the command handler in the code behind. If you are using a separated presentation pattern such as MVVM, for example, you could place the command declaration and the command handlers in your ViewModel, as exemplified in the sample I’ve provided to you.

If you are trying to bind different events to different commands, you could use the snippet from Damian’s blog. In that case, you would be using Attached Behaviors to bind different events in your control to separate instances of DelegateCommand. On the other hand, the CompositeCommand is used to group several child DelegateCommands into a single command, bound to a single event in a control (for example, a SubmitAll button that, when clicked, executes multiple Submit commands). You can check the Commanding Quickstart to see more examples of the usage of CompositeCommands.

As an additional note, take into account that the EventAggregator is useful for communication between modules (as shown in the sample). If you need to communicate between views in the same module, you could use regular .NET events instead of the EventAggregator.

2) If you implement ICommand, you must place the Execute and CanExecute methods inside the concrete class inheriting from it. Since you are not using delegates, you would need to create a new command type for every instance where you need commanding, and you wouldn’t be able to place the handlers (that is, the Execute and CanExecute methods) for that command in some other place. You can read more about delegates in this article.

You can find more information about commanding in Prism in this article from the documentation.

I hope you find this helpful.

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

Jun 19, 2010 at 1:52 PM
Edited Jun 20, 2010 at 5:09 PM

Thanks a lot! Very clearly and in detail. I looked into the MSDN:

"Commands in WPF are created by implementing the ICommand interface. WPF provides a number of classes which implement ICommandSource, such as Button, MenuItem, and ListBoxItem. WPF supplies a set of common routed commands spread across several classes: MediaCommands, ApplicationCommands, NavigationCommands, ComponentCommands, and EditingCommands. These classes consist only of the RoutedCommand objects and not the implementation logic of the command. "

In such a way we have only 'click behavior' for Button, MenuItem, and ListBoxItem. A shorthand notation like this: Command="{Binding MyCommand}" as you demonstrated in sample.

Application and Editing commands is not enough for rich internet/desktop applications. Therefore, we will describe their own behavior for all other controls and events :(

May be easier to decribe the menu and windows behaviour in code-behind in the ordinary way and to use composite command only for special business logic buttons ( database or service calls) ?

Jun 19, 2010 at 5:12 PM
Edited Jun 19, 2010 at 5:13 PM
"As an additional note, take into account that the EventAggregator is useful for communication between modules (as shown in the sample). If you need to communicate between views in the same module, you could use regular .NET events instead of the EventAggregator." Hello guidomaliandi, Could you please explain / give an example of what you mean by regular .NET events. Also who would it matter if it's within the same module or not ? Thanks, Richard One last question to anyone out there. How the heck can I make it so the text goes on multiple lines?
Jun 25, 2010 at 7:04 AM

What do you think about my last post? MVVM or not MVVM at UI ?:)

Developer
Jun 25, 2010 at 8:49 PM

Hi SpaceMarine,

Using Delegate Commands or not depends on whether you want to benefit from the advantages of separating UI logic from UI layout and presentation. Choosing to place the handlers for the menu and windows actions in the code behind of your view would make the view responsible for executing those actions, which, as you’ve mentioned, breaks the MVVM pattern. That decision depends on what you want to achieve. Based on your scenario, you could consider if the benefits of MVVM are worth the overhead of having to define the custom command behaviors. For example, if you place any behavior in the code behind files, it will be hard to create unit tests for it.

Another possibility to avoid the overhead of defining custom command behaviors, while keeping the benefits of MVVM would be to use Blend Behaviors Triggers and the InvokeCommandAction behavior to specify that a command should be invoked on certain event. The code for that would look like this:

<ListBox x:Name="QuestionnaireTemplatesList" 
                 ItemsSource="{Binding QuestionnaireTemplates}"  >
            <i:Interaction.Triggers>               
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding QuestionnaireTemplateChangedCommand}" />

Note that this sample was taken from the MVVM Quickstart in Prism 4.

I hope you find this helpful.

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

Developer
Jun 25, 2010 at 8:50 PM

Hi Richard,

When I said regular .NET events I was referring to just simply using the event keyword as opposed to using the CompositePresentationEvent provided by Prism. You can see examples of regular .NET events in this article from MSDN.

I made that distinction because the CompositePresentationEvent class, which is the kind of events that the Event Aggregator can contain, is useful for decoupling the subscriber from the publisher of an event. If the subscriber and the publisher are located in the same module, there is no need for decoupling between them. Therefore, you don’t have to use CompositePresentationEvents.

I hope you find this helpful.

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

Jul 21, 2010 at 7:49 AM

Many thanks!

After installing Blend 4 and using expression/2010/interactions and interactivity i simply created commands for different events.

Now tell as a geek: how would be better to associate view and viewmodel?

     public partial class MyView: UserControl
        {
            public MyView(MyViewModel viewModel) {}  // channel9
        }

or

     public MyViewModel(IService service, IEventAggregator eventAggregator, IMyView view)
        {
            this.View = view;
            this.View.Model = this;    // StockTraderRI
            this.service = service;
            this.eventAggregator = eventAggregator;
        }

In which way is easier to manage the view from the viewmodel? At my commands i needed to edit control properties.

Jul 22, 2010 at 12:22 AM

SpaceMarine: You might want to look at Drop 4 of Prism 4 that is available in the downloads. One of the current focuses in Prism 4 is MVVM. The drop includes a Basic MVVM example, an MVVM QuickStart, and an MVVM RI. We are getting away from the ViewModel-first approach in the Prism 2.2 and prior samples and are favoring View-First approach (view XAML hooks up the view model most often) because it works better with designers.

Aug 17, 2010 at 6:37 AM
Edited Sep 10, 2010 at 3:07 PM

reworking solution started :(