Behaviors in Silverlight with the Expression SDK

Prior to the Expression SDK, you had two main choices to create reusable behaviors that could be applied to UI elements. First and most obvious is to subclass a control type and add whatever functionality you wanted. For instance, if you wanted a TextBox to raise an event (or execute an ICommand) whenever the Enter key was pressed, you could create a subclassed TextBox and add that.

The second way was to create manual “attached behaviors” via a trick commonly used in WPF with attached properties. In short, you create an attached property and use the property change notification to attach to events. Using the earlier example, here is a working attached behavior that exeuctes an ICommand on enter key press in a TextBox:

The meat of the code comes from lines 36-60. On 40-45, we attach or detach an event handler to the KeyDown event depending on whether the supplied ICommand is null. Then on lines 49-60 we handle the KeyDown event and execute the command. To use this behavior, just reference it inside a TextBox:

All that is needed is the ViewModel/DataContext expose an ICommand property called ExecuteSearch and now we’ve got a way to repeatedly apply a common behavior to any TextBox in our application without much effort.

One thing you may notice here, however, is our behavior describes not only the action to be taken, but also the condition in which it happens. This is limiting and can end up causing duplicated code as we create variants of our shared behaviors. Enter the Expression SDK.

The Expression SDK (in particular, two assemblies: System.Windows.Interactivity and Microsoft.Expression.Interactions) breaks this up into separate concerns. With it you can create the “when” (a trigger for instance) and the “what” (an action for instance) separately to more easily mix and match. In the Expression SDK there are behaviors, triggers and actions. Behaviors are all-in-one sets of reusable functionality like we did above, but from here on I’ll only be discussing triggers and actions, which enable us to separate the when and the what.

The trigger for the enter key pressed behavior is the enter key being pressed inside a TextBox. To represent this, we create a class that inherits from TriggerBase:

We override OnAttached and subscribe to the TextBox’s KeyDown event and when the Enter key was pressed we call the InvokeActions method. Very svelte and to the point. What about the action though? Luckily, the Expression SDK has support for invoking a command built in via the InvokeCommandAction, so we’re done except for our XAML:

What if we wanted to do something other than invoke a command? With the full DIY attached property behavior, we’d have to create a new class that contained the new behavior. By factoring our trigger out into a class, we can use any of the built-in actions. What if we wanted to set the user control’s background to green?

If you have an action that’s not natively supported by the Expression SDK, you can create a class that inherits from TriggerAction.

For more info, see this Expression blog post on Behaviors, Triggers and Actions.

Leave a Reply