In my previous post, I explained the basics of how to write a simple behavior. I concluded by mentioning that a behavior can actually be made to work with triggers. This is possible despite a Behavior having no real mechanism for a trigger to bury itself into. How is that possible? This post will explain how.
I may have lied a little bit. My previous explanations of Behaviors being solo-artists is not entirely accurate. While Behaviors can work independently without any external influence, unlike an Action, they can also be made to do certain things when certain conditions are met:
That is why the condition part of the original sentence is grayed out as opposed to completely .being removed.
Your Wish is My ICommand
If you want your behavior to be capable of being triggered, you can expose Commands (anything of type ICommand) to be the function that will get called. If you are confused about what I just wrote, don’t worry. Let’s write a behavior that demonstrates this. First, make sure your project has a reference to both the Microsoft.Expression.Interactions and Microsoft.Expression.Interactivity DLLs.
After you have done that, create a new Class file, and before you do anything else, add the following using statement:
- using Microsoft.Expression.Interactivity.Input;
Once you have done this, add the code to turn your class into a behavior:
- public class BehaviorWithCommand : Behavior<DependencyObject>
- public BehaviorWithCommand()
- this.MyCommand = new ActionCommand(this.MyFunction);
- protected override void OnAttached()
- protected override void OnDetaching()
- public ICommand MyCommand
- private set;
- private void MyFunction()
- MessageBox.Show("Hello World");
Note that I call my behavior BehaviorWithCommand, so be sure to rename your class name and constructor appropriately instead of using my name if you copy/paste. Save and build your project to make sure everything works and nothing is complaining.
Looking at the Blend 3 UI
Go ahead and apply this Behavior any element in your Silverlight or WPF application. Once you have added it to something, select this behavior and look at what is displayed in your Properties Inspector:
Notice that you now see a category called MyCommand, the name of your ICommand property specified in code.
From this category, on the top-right corner, you can use the plus button to add the triggers that will invoke your MyCommand command:
This UI may be new to you if you’ve never played with Behaviors that expose Commands. With commands, notice that I am not stuck with just one Trigger. I am able to add multiple triggers that can each call the same MyCommand function, and just like with Actions, I have the ability to modify the properties of my trigger as well!
How this Works Behind the Scenes
What you see in the Blend UI is a major abstraction of what goes on behind the scenes. To help you understand what is happening better, the following diagram gives you an overview of how commands and Behaviors work together to give you Action-like abilities:
Notice that your behavior exposes a command, and there exists an Action called InvokeCommandAction that does nothing but, as it name implies, invoke commands. Since this is an Action, you have the abilities to set triggers on it. All you ever see in the Blend UI is the Command and the Triggers that you want to set on it. Behind the scenes, we map your trigger to the InvokeCommandAction that is associated with the Command.
This means the trigger has no knowledge of the behavior. They are completely decoupled and fit with the self-contained, solo model that I have been describing about Behaviors for the past few posts. Because they interact with Actions that, in turn, interact with Commands exposed by the Behavior, you have the ability to have our behavior do things with some external input just like you can with Actions.
All right. This wraps up my current series of posts describing Behaviors themselves. You may find yourself wondering why you would ever want to use a Behavior when Actions just seem much easier to use and conceptually understand. The answer is, for the most part, rarely.
Unless you want the ability that Behaviors have where you can internally manage state independent of being tied to a trigger, you will find a Trigger and Action pair to be your best friends as you navigate through this sea of interactivity. For a class of interactions, especially those involving state, having a Behavior handy does not hurt either though.