Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

19 Oct 2009

Separation of concerns: Behavior = Trigger + TriggerAction

If you look at my KeyBehavior you notice that it is doing two things: register for events so that the behavior can be triggered and handle the actual command invocation. In order to enhance reuse we can refactor this KeyBehavior in a KeyTrigger and an InvokeCommandAction. Well, we’re not going to do that, because they exist already in the silverlight sdk.

A shortcoming of the InvokeCommandAction is that it can only invoke commands on the FrameworkElement itself, thus we write a custom implementation that finds commands on the DataContext instead

public class InvokeCommandAction : TriggerAction<frameworkElement>
{
	public string CommandName { get; set; }

	protected override void Invoke(object parameter)
	{
		var viewModel = AssociatedObject.DataContext;
		GetCommandAndExecuteIt(viewModel, CommandName);
	}

	void GetCommandAndExecuteIt(object viewModel, string commandName)
	{
		var command = viewModel.GetPropertyValue<icommand>(commandName);
		if(command.CanExecute(null)) command.Execute(null);
	}
}

And now we can drag this action on our design surface in Blend and select a trigger that goes with it

choosing a keypress trigger in blend

All we have to do is choose the Key and Command to invoke

setting properties for action in blend

In XAML this looks like

<interactivity:Interaction.Triggers>
	<ii:KeyTrigger Key="Right">
		<inf:InvokeCommandAction CommandName="PlayerRight"/>
	</ii:KeyTrigger>
	<ii:KeyTrigger Key="Left">
		<inf:InvokeCommandAction CommandName="PlayerLeft"/>
	</ii:KeyTrigger>
	<ii:KeyTrigger Key="Up">
		<inf:InvokeCommandAction CommandName="PlayerUp"/>
	</ii:KeyTrigger>
	<ii:KeyTrigger Key="Down">
		<inf:InvokeCommandAction CommandName="PlayerDown"/>
	</ii:KeyTrigger>
</interactivity:Interaction.Triggers>

I guess this ends our exploration of the behavior features in Silverlight.