MVVM Fabric: Using TriggerAction

A few days ago, I wrote about using MVVM Fabric’s ActionCommand.  Commanding can be useful with controls that provide a Command property, such as Buttons and MenuItems.  However, commanding doesn’t help when you want to wire up arbitrary events to your view model.  That is where TriggerAction come in.

Overview

TriggerAction is a look-less framework element that wires itself up to whatever event you specify on whatever control you specify.  When that event is raised, TriggerAction calls whatever method you specify on your view model.

TriggerAction was written by Rocky Lhotka for his business object framework, CSLA .NET.  Since CSLA is open source, Rocky gave me permission to include TriggerAction with MVVM Fabric because of the great value it would provide consumers of the library.  I have been using a precursor of TriggerAction, called InvokeMethod, on my projects with great success.  While InvokeMethod has some limitations (no designer support and the ability to only wire one event for a control), TriggerAction provides a more robust implementation and eliminates these issues.

Wiring an event to a method

There’s really two different ways that I typically use TriggerAction.  The first way is when I really only care if an event happened.

For this example, we will wire up TriggerAction to call the Close method on our view model when a button is clicked.  We first need to name the button that we will be hooking events from.

Next we place the TriggerAction on our view.

Notice that I used an Element Binding for the TargetControl property.  That is how we tell TriggerAction to listen for the click event on our button.  I also set the MethodName property with the name of the method we want called.  It is important to note that TriggerAction looks for the method specified on its DataContext.  So, you have to make sure that the DataContext is your view model if you want it to call methods on your view model.

Now we need to write the Close method on our view model.

We’re all set.  When the Click event is raised on our button, TriggerAction will look for a method called Close on its DataContext (which is our view model).  The method it looks for must have 0 or 2 arguments.  We have the 0 argument version here because we only care that the event happened.

Wiring an event to a method with a MethodParameter

The second way I typically use TriggerAction is for those situations where I need to pass a parameter to my method when the event I care about is raised.

For this example (and the one you will see in the sample application), we will wire up the MouseDoubleClick event on a ListView to pass the SelectedItem back to our method on the view model.

First, the ListView.

 

Next, the TriggerAction.

 

There are two things different about our usage of TriggerAction here.  The first difference is the addition of the MethodParameter property, which we are binding to the SelectedItem property on the MoviesList element.  The second is setting RebindParameterDynamically to true.

The MethodParameter property on TriggerAction is where you bind whatever you want from the view to be passed back your view model.  This can be something on the element you are listening for events on or something somewhere else on the view.

The RebindParameterDynamically property is really cool.  When this is set to true, TriggerAction will go out and rebind to the method parameter before calling back to your method so that you are always sending back the latest and greatest.  Since not all of the properties you want to bind to raise property changed events, this is a huge benefit.

Now, on to the view model.  As I mentioned before, when looking for methods on our view model, TriggerAction will look for methods with either 0 or 2 parameters.  Since we need that MethodParameter passed in, we will need the 2 parameter version.

 

This is a typical event handler method signature.  The event args that are passed through are ExecuteEventArgs, which have some useful properties.  The property we care about right now is the MethodParameter property, which needs to be cast before we use it because it is of type Object.  Once we cast it as our Movie business object, the view model is free to do what it needs with it.

Conclusion

Although commanding is a decent start to executing methods on your view model, TriggerAction is a much more robust solution.  With drag-and-drop designer support, the ability to bind a method parameter and the ability to have that method parameter dynamically updated at execution time, TriggerAction is an extremely powerful way to wire arbitrary events from your view to your view model.

Share

MVVM Fabric: Using ActionCommand

The first thing I am going to discuss in my series describing my new WPF library, MVVM Fabric, is ActionCommand.  ActionCommand is an implementation of the ICommand interface.  The ICommand interface is interesting because it can be used in WPF and Silverlight as a way to route certain events (such as clicks) from the view to the view model.

Now, there’s nothing stopping you from doing custom implementations of the ICommand interface for every command your application needs.  I found that to be overkill, however, because in every case I just wanted to turn around and call some method when the command was executed.  Enter ActionCommand.

ActionCommand provides a way to create commands that will call methods on your view model when executed.  MVVM Fabric provides two flavors of ActionCommand, a plain one and a generic one.

Plain ActionCommand

The plain ActionCommand is great for those situations where you just want to execute some method on your view model and have no need for a parameter.  It’s usage is quite simple.

The above example has a method called Save which needs to be called from the view.  So, an ICommand property, called SaveCommand, is exposed on the view model.  In the view model’s constructor, SaveCommand is instantiated with an instance of ActionCommand.  The plain ActionCommand takes a plain Action as its parameter.  A plain Action is a method that has no parameters and a void return type.

To leverage this command, we need to wire up something like a Button to it.  With our view model already defined as the DataContext, the following XAML will do that for us.

Now, when the button is clicked our Save method will be executed on the view model.

Generic ActionCommand

The generic flavor of ActionCommand is useful for those situations where you want to execute some method but also need a parameter to be passed in.  WPF allows you to bind a CommandParameter along with the Command.  The generic part of the generic ActionCommand defines what type that CommandParameter is.  The usage is a little more complicated than the plain ActionCommand, but not by much.

As you can see, the generic ActionCommand uses an Action which takes a parameter type as defined by the generic parameter.  The view side looks a little different too.

Notice that we now have a binding set up on the CommandParameter property.  That binding tells WPF what to pass to the Command as a parameter, which ultimately ends up passed to the SelectMovie method. 

NOTE: If you are looking at the sample application included with MVVM Fabric, you’ll notice that the binding expression I am referencing is more complex.  That is due to the fact that the binding occurs in a DataTemplate, which has a Movie as it’s DataContext, the the MovieCommand lives on the view model.  I used some binding-fu to bind to two different DataContexts.

Conclusion

So, there we have it.  Commanding is not the ultimate solution to wiring events from the view to the view model, but it does work well for some cases.  When commanding applies, ActionCommand is a clean and simple way to leverage it.

Share