Like I’ve mentioned several times earlier, behaviors in Expression Blend 3 are made up of extensible Triggers, Actions, and Behaviors. What I really have not done is explain in greater conceptual detail what each of those pieces do and how far you can push our default implementation. In this post, let’s fix that by giving Triggers and Actions their long-awaited detailed overview.
In a Nutshell
If I had to sum up what triggers and actions do, the following sentence is it:
Pretty simple, right? Let me take a few steps back and look at a few examples. When I flip on a light switch switch, the light needs to turn on. When I click on a button, a sound needs to play. When I hit a certain time, the application should close. What I have just described are simple cause-and-effect relationships, and in a nutshell, Triggers and Actions are nothing more than digital manifestations of them. The cause (When) is controlled by the Trigger, and the effect (Do) is controlled by the Action:
All of the examples involving Actions that I have shown you over the past few blog posts follow a similar pattern:
In the Blend UI, we suppress a lot of the details for you. You only drag and drop an Action onto an element, and the trigger is either automatically set as specified by the Action, or you can set it yourself. That seems simple…sort of!
Sneaky Like a Fox
What makes Triggers and Actions more interesting is how sneaky they actually can be. When you drag an Action onto an element in Blend, your Action is parented under this button:
What is worth looking into is what the Trigger and Action are looking at, and let’s assume the Trigger we are looking at is an EventTrigger. Dropping an Action onto the above button will set the Trigger’s source to that of the button itself, and it will also set your Action’s target to be that of the button as well:
What you have the ability to do is set the Source to some other element besides your button. Let’s say you have a checkbox you want to set as your EventTrigger’s Source instead.
With our current Behaviors implementation, you can simply change the Source of your Trigger to that of your checkbox very easily by setting the Trigger’s SourceName property to that of your checkbox:
This means that your Action will do something when the event you are listening for on your CheckBox fires.
You’ve just seen how we can set the source of a trigger, our EventTrigger, to that of another element besides the one your Action is parented under. To make things a bit more interesting, you also have the ability to target your Action to affect an element other than the one you are parented under as well!
If your Action inherits from TargetedTriggerAction instead of just TriggerAction, you gain access to the TargetName property that allows you to specify which element you want your Action to affect. So you can have something such as the following:
Your Action is parented under the Button, but your EventTrigger is actually listening for events from a CheckBox. When the trigger fires, your Action does its thing on a blue rectangle that it is targeting.The actual Button is merely the Action’s host and it derives no benefit from it because neither the Action nor the Trigger care about it. Sad, isn’t it?
Rationale Behind This
Right now, you are probably wondering why we allow you to do something like this. It isn’t as if you have to manually modify XAML for this. We provide UI today that allows you to easily do this. The reason has to to do with different approaches individuals have on how the relationship between a trigger and Action should work.
I tend to like the following approach where my Action is on the element that will be the Source of my trigger:
This is known as the Tell approach because I am telling my Action to affect something else. The other approach is known as Listen, and it is where you place your Action on the element that is being affected as opposed to the Source of the trigger:
There is no right or wrong way to approach how you wire up your Triggers and Actions. The thing to note is that our Behaviors API is flexible enough to support both, and our UI makes it easy for you to pick either Listen or Tell without having to do anything crazy.