MVVM event to command binding #2: Behaviors and event triggers

The recommended way of coupling user control events and Viewmodel Commands is the use of behaviors or event triggers. This approach is available for most platforms and XAML dialects, although detailed implementations differ. Let’s take a look at how to use this approach, and then discuss its benefits and drawbacks!

Windows Store / Phone / Universal Apps:

In Windows 8 / Windows Phone 8 App projects, we first need to reference the Behavior SDK which is available as an extension to the WinRT framework: Right click References in the Solution Explorer, choose Windows > Extensions in the Reference Manager window, and select the Behaviors SDK (XAML) entry:

Add a reference to the Behaviors SDK

In contrast, on the Windows 10 UWP platform it’s recommended to reference the XAML Behaviors NuGet package (search for Microsoft.Xaml.Behaviors.Uwp.Managed in the NuGet package manager and install the latest version).

In addition, on both platform we need to declare two namespaces in the header of each View that will contain an event-to-command binding:

<Page xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:core="using:Microsoft.Xaml.Interactions.Core" ... >

Now we’re able to attach an EventTriggerBehavior to any user control’s event:

<Button>
	<interactivity:Interaction.Behaviors>
		<core:EventTriggerBehavior EventName="DoubleTapped">
			<!-- TODO -->
		</core:EventTriggerBehavior>
	</interactivity:Interaction.Behaviors>
</Button>

The EventTriggerBehavior can be passed an Action (or, in more complex scenarios, a collection of several actions) to be executed when the event is fired. We’re using the predefined InvokeCommandAction that allows us binding to a Command present within the Viewmodel:

<Button>
	<interactivity:Interaction.Behaviors>
		<core:EventTriggerBehavior EventName="DoubleTapped">
			<core:InvokeCommandAction Command="{Binding SomeCommand}" />
		</core:EventTriggerBehavior>
	</interactivity:Interaction.Behaviors>
</Button>

WPF & Silverlight platforms:

On the WPF and Silverlight platforms (this even includes Windows Phone Silverlight projects!), we’re working with event triggers. Using the Reference Manager window, add System.Windows.Interactivity to the project’s references, and declare the following namespace in each View’s header:

<Window xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" ... >

Add reference to System.Windows.Interactivity

We can now add event triggers to any control:

<Button>
	<i:Interaction.Triggers>
		<i:EventTrigger EventName="MouseDoubleClick">
			<!-- TODO -->
		</i:EventTrigger>
	</i:Interaction.Triggers>
</Button>

Inside the trigger follows an instance of the InvokeCommandAction class we know already:

<Button>
	<i:Interaction.Triggers>
		<i:EventTrigger EventName="MouseDoubleClick">
			<i:InvokeCommandAction Command="{Binding SomeCommand}"/>
		</i:EventTrigger>
	</i:Interaction.Triggers>
</Button>

Discussion:

The main advantage of this approach is that it is available for all platforms (although realized in different ways, using either triggers or beahviors). An additional benefit is its flexibility: There exist additional predefined Actions in addition to the InvokeCommandAction that allow various actions to be carried out without writing one single line of C# code, and custom actions may be defined and then referenced in XAML code. Moreover, all those actions (predefined as well as custom-made) can be combined, since both EventTriggers and EventTriggerBehaviors accept collections of actions, all of which are executed when the specified event is triggered.

On the other hand, this approach is rather verbose. This need not be a disadvantage as it makes the code self-explanatory, but especially in simple cases as the one shown above (simple event-to-command binding without additional actions), I find it unnecessarily lengthy – the full Button declaration now takes 7 lines of XAML code, making the View code unnecessarily complex and more difficult to read. Especially beginners might be tempted to fall back to the use of traditional event handlers, taking into account that these can be desclared with only a few characters of XAML code (compared to the above-mentioned 7 lines).

In summary, the behavior / event based approach is the perfect solution for complex scenarios that combine multiple actions to be triggered for the same event. However, for simple event-to-command binding, there must be a shorter way. Let’s take a look at another approach in part #3 of this series of articles!