Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Creating Silverlight Behaviors (with Blend 3 Interactivity dll)

Behaviors are not new in WPF / Silverlight world; it’s a common way of extending visual element’s behavior through the power of attached properties and everybody probably used one of these at least once in their projects. Now, there’s new Behaviors in town…

I first learned about the behaviors in this excellent, short but sweet MIX09 presentation by Pete Blois. In short: the new “breed” of behaviors will be supported in Blend 3, allowing designers to easily extend visual elements by drag’n’dropping a variety of behaviors onto them. If you’re not familiar with what behaviors are – imagine you have a Drag behavior... By setting it to any element in your window (in Blend / Xaml, no .NET code!), that element instantly gets draggable around that window. Yeah, that’s a powerful concept. And it doesn’t stop there. Watch the video, it’s worth the time…  And for detailed info, Christian is running a series on behaviors and other interactivity mechanism in his blog.

What I don’t get is why they are called Blend (3) behaviors, because they are not limited to Blend in any way. They would be as easily called Silverlight/WPF behaviors, or simply – Behaviors. Yes, that means you can use (and create) them even if you don’t have Blend 3 installed. Even Silverlight 3 is not required, it works with version 2 perfectly. You only need a special dll, which gets installed with Blend 3 – Microsoft.Expression.Interactivity.dll. I currently have no idea what the deployment story with this assembly is at the time of the writing (with Blend being in Beta and all), but you’ll find it in the c:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\[Silverlight] | [WPF]\ folder. This assembly (it comes in Silverlight and WPF flavor) provides the base interactivity classes and is required if you’re going to use behaviors in your application.

It should be quite obvious as to where behaviors fit in the designer / developer workflow: designers will be able to decorate visual elements with various behaviors and see them in action, while developer’s job will be to come up with new, not-yet-existing behaviors that designer had in mind when designing the UX.

There are a few examples of behaviors up and ready on Expression Gallery, but let’s take a look how we can develop our own behaviors using Visual Studio 2008.

The first behavior we’ll look into will be called the TransparencyBehavior. What it will do is make every element semi-transparent when the mouse is not directly over it. I’ll use one of my previous samples (a semaphore) as a building ground for this one. The lights on the semaphore will be semitransparent until mouse enters the light’s space for it to become fully visible. Let’s begin

First, you’ll need the Expression interactivity dll (see above). Once you find it, add it as a reference to your project. Then, create a class, deriving from Behavior<T>. The generic type T is the type of element you want to extend with this behavior. I’m using the Ellipse type for the purpose of this example to show a more concrete implementation. I could also use <FrameworkElement> because this type of behavior is so common it could be attached to element.

Update: updated the previous paragraph to make sense and align with the sample code.

public class TransparencyBehavior : Behavior<Ellipse> {}

We’ll need a couple of properties to control the behavior’s parameter: The InactiveTransparency property will hold an opacity value for element’s inactive state (when the mouse is not over) and the Duration will hold the time for the element to transition from active to inactive state (and vice versa).

To hook into the element we’re extending, we have to override the OnAttached method. It will be called when the element is being initialized so we have the chance to attach additional event handlers to element’s events. The extended element can be reached through the AssociatedObject property. In this method, I’m hooking up into MouseEnter and MouseLeave events to detect when mouse is over, initialize and construct a storyboard that will be triggered for state transition:

protected override void OnAttached()
{
    base.OnAttached();

    storyboard = new Storyboard();
    animation = new DoubleAnimation();
    animation.Duration = Duration;
    Storyboard.SetTarget(animation, AssociatedObject);
    Storyboard.SetTargetProperty(animation, new PropertyPath(Border.OpacityProperty));
    storyboard.Children.Add(animation);

    AssociatedObject.Opacity = InactiveTransparency;
    AssociatedObject.MouseEnter += OnMouseEnter;
    AssociatedObject.MouseLeave += OnMouseLeave;
}
Similarly, there's the OnDetaching method that we can use to clean up (remove event handlers etc.) The rest of the class are just the handlers:
 
void OnMouseLeave(object sender, MouseEventArgs e)
{
    animation.To = InactiveTransparency;
    storyboard.Begin();
}

void OnMouseEnter(object sender, MouseEventArgs e)
{
    animation.To = 1;
    storyboard.Begin();
}
 
To finish, here’s a piece of modified (from the previous semaphore example) piece of Xaml using the behavior:
 
<Ellipse Fill="{Binding Brush}" Width="50" Height="50" Stroke="Black">
    <i:Interaction.Behaviors>
        <local:TransparencyBehavior Duration="00:00:00.2" InactiveTransparency="0.5" />
    </i:Interaction.Behaviors>
</Ellipse>
That’s all for this simple behavior. In future posts, I’ll come up with new behaviors and put them in the context of some other samples I’ve used in the previous posts.
[Hint: in the below sample, hover over green lights]

The way to create new behaviors is very similar to using “direct” approach with attached properties. The Behavior base class provides a very convenient infrastructure to build on, and porting the “old way” attached behaviors to this new model shouldn’t be that difficult. Behaviors are not limited to use in Blend 3 and work with Silverlight 2 too. With that, it would be great to see Microsoft releasing the interactivity dll as a standalone release or a part of some other SDK, not tying it to either Blend 3 or any particular Silverlight version.

The source code for this sample is available. Please note that the project is a Silverlight 3 project and doesn’t include the Expression Interactivity dll.

Update: the above code was updated to match Silverlight 3 / Blend 3 RTM bits. Thanks To Michael Washington for taking the time to update the behavior.

Shout it