Bookmark and Share Share...    Subscribe to this feed Feed   About Christian Moser  


Behaviors

A simple Border can be dragged by mouse - because of an attached drag behavior.

Introduction

Behaviors are a new concept, introduced with Expression Blend in Version 3, to encapsulate pieces of functionality into a reusable component. These components than can be attached to controls to give them an additional behavior.

The ideas behind behaviors are to give the interaction designer more flexibility to design complex user interactions without writing any code.

Example of a behaviors are drag&drop, input validation, pan and zoom, re-position of elements, etc... The list of possible behaviors is very long.

Imaging an application that has a list of customers and the user can add some of them to subscriber lists. This interaction can be designed by providing an "Add" button next to each subscriber list. But if the interaction designer wants to add drag&drop functionality, he needs to discuss it with the developer and wait until the implementation is done. With behaviors he just drags a drag and drop behavior on each list and we are done.

How to use behaviors in Expression Blend 3

Using behaviors in Expression Blend is as simple as adding an element to the design surface. In the asset library you find a new secion called "Behaviors". It lists all behaviors available within your project. Just grab one of these and drag it onto the element you want to add this behavior and thats it.

The behavior appears as an child element in the visual tree. By clicking on it you can configure the properties of the behavior.



How does it work

To add behaviors to an element you need some kind of an extension point. This is an attached property called Interaction.Behaviors.
This attached property holds the list of behaviors for that element and pass a reference to the element into the behavior. The behavior than can register itself to events and property changes and so extend the functionality of the element.

The idea is simple, but very clever. They don't need any new infrastructure, they just reuse the existing one.

 
<Border Background="LightBlue" >
	<e:Interaction.Behaviors>
		<b:DragBehavior/>
	</e:Interaction.Behaviors>
	<TextBlock Text="Drag me around!" />
</Border>
 
 

How to implement your own behavior

The following example shows the implementation of the drag behavior we used above. Just derive from Behavior<T;gt; and override the OnAttached() method.

 
public class DragBehavior : Behavior<UIElement>
{
    private Point elementStartPosition;
    private Point mouseStartPosition;
    private TranslateTransform transform = new TranslateTransform();
 
    protected override void OnAttached()
    {
        Window parent = Application.Current.MainWindow;
        AssociatedObject.RenderTransform = transform;
 
        AssociatedObject.MouseLeftButtonDown += (sender, e) => 
        {
            elementStartPosition = AssociatedObject.TranslatePoint( new Point(), parent );
            mouseStartPosition = e.GetPosition(parent);
            AssociatedObject.CaptureMouse();
        };
 
        AssociatedObject.MouseLeftButtonUp += (sender, e) =>
        {
            AssociatedObject.ReleaseMouseCapture();
        };
 
        AssociatedObject.MouseMove += (sender, e) =>
        {
            Vector diff = e.GetPosition( parent ) - mouseStartPosition;
            if (AssociatedObject.IsMouseCaptured)
            {
                transform.X = diff.X;
                transform.Y = diff.Y;
            }
        };
    }
}
 
 

List of some popular behaviors

Since its so cool and easy to create your own pice of interactivity, I am sure that we will find hunderts of behaviors available soon. I tried to make a list of some popular ones.





Last modified: 2009-04-20 21:07:27
Copyright (c) by Christian Moser, 2011.

 Comments on this article

Show all comments
Martin Ortiz
Commented on 3.January 2010
SWEET!!
Learning WPF, and heard about behaviors.

Nice short / concise article..plus good list of additional behaviours.
Martin Ortiz
Commented on 3.January 2010
SWEET!!
Learning WPF, and heard about behaviors.

Nice short / concise article..plus good list of additional behaviours.
Martin Ortiz
Commented on 3.January 2010
SWEET!!
Learning WPF, and heard about behaviors.

Nice short / concise article..plus good list of additional behaviours.
pooja
Commented on 5.January 2010
hi..can u tellme how i can add additional behavoiurs like glass behaviour into my project.....
Ever (Spanish)
Commented on 14.May 2010
it works fine the first time I drag and drop the attached control. The other times it translates when the mouse is down, before dragging.
martin
Commented on 7.June 2010
yep, what Ever said. some please explain how to solve this, was not able to figure that out yet. thanks in advance
C-MOSEY
Commented on 23.August 2010
I apprieciate your feedback but I cant explain it anymore in depth because I just copy and pasted this from another website
Edvald
Commented on 4.October 2010
Well I can. In this code, the transformation is set to the movement vector of the mouse cursor but should be set to (previous translation) + (movement vector):
<code>
Window parent = Application.Current.MainWindow;
AssociatedObject.RenderTransform = transform;

AssociatedObject.MouseLeftButtonDown += (sender, e) =>
{
mouseStartPosition = parent.PointToScreen(e.GetPosition(parent));
AssociatedObject.CaptureMouse();
(AssociatedObject as TextBlock).Text = mouseStartPosition.ToString();
};

AssociatedObject.MouseLeftButtonUp += (sender, e) =>
{
AssociatedObject.ReleaseMouseCapture();
elementStartPosition.X = transform.X;
elementStartPosition.Y = transform.Y;

};

AssociatedObject.MouseMove += (sender, e) =>
{
var parentPos = parent.PointToScreen(e.GetPosition(parent));
Vector diff = (parentPos - mouseStartPosition);
if (AssociatedObject.IsMouseCaptured)
{
transform.X = elementStartPosition.X + diff.X;
transform.Y = elementStartPosition.Y + diff.Y;
(AssociatedObject as TextBlock).Text = diff.ToString();
}
};
</code>
Edvald
Commented on 4.October 2010
Also, remove the "(AssociatedObject as TextBlock).Text = ..." lines as they are only for debugging :)
Edvald
Commented on 4.October 2010
Sorry about the spam, please delete the comments above, here's a cleaned up version:

protected override void OnAttached()
{
Window parent = Application.Current.MainWindow;
AssociatedObject.RenderTransform = transform;

AssociatedObject.MouseLeftButtonDown += (sender, e) =>
{
mouseStartPosition = e.GetPosition(parent);
AssociatedObject.CaptureMouse();
};

AssociatedObject.MouseLeftButtonUp += (sender, e) =>
{
AssociatedObject.ReleaseMouseCapture();
elementStartPosition.X = transform.X;
elementStartPosition.Y = transform.Y;

};

AssociatedObject.MouseMove += (sender, e) =>
{
var mousePos = e.GetPosition(parent);
Vector diff = (mousePos - mouseStartPosition);
if (AssociatedObject.IsMouseCaptured)
{
transform.X = elementStartPosition.X + diff.X;
transform.Y = elementStartPosition.Y + diff.Y;
}
};
}
RItty
Commented on 19.August 2011
Great Article
RItty
Commented on 19.August 2011
Great Article

Name
E-Mail (optional)
Comment