How can you use the Visual State Manager to create a hover effect?

Silverlight Hover Behavior.

One example of creating a good user experience is providing visual feedback when a user hovers over a UI Element. This is easily accomplished with the Silverlight Visual State Manager. As an alternative you can create two storyboards (StoryboardMouseEnter and StoryboardMouseLeave) that handle the hover behavior:

hover

hover

To trigger these storyboards, you can use two ControlStoryboardActions:

trigger

To simplify this process, I created a Behavior that wires two storyboards to the MouseEnter and MouseLeave of a UI Element.

Creating a dedicated MouseHover behavior

Create a new Behavior in Microsoft Expression Blend and added two Dependency Properties.

#region MouseEnterStoryboard Dependency Property

[CustomPropertyValueEditor(CustomPropertyValueEditor.Storyboard)]
public Storyboard MouseEnterStoryboard {
get { return (Storyboard)GetValue(MouseEnterStoryboardProperty); }
set { SetValue(MouseEnterStoryboardProperty, value); }
}

public static readonly DependencyProperty MouseEnterStoryboardProperty =
DependencyProperty.Register("MouseEnterStoryboard",
                        typeof(Storyboard),
                        typeof(HoverBehavior),
                        new PropertyMetadata(null, OnMouseEnterStoryboardPropertyChanged));

private static void OnMouseEnterStoryboardPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var owner = d as HoverBehavior;
if (owner != null) {
//TODO: Handle new value.
}
}

#endregion MouseEnterStoryboard Dependency Property

#region MouseLeaveStoryboard Dependency Property

[CustomPropertyValueEditor(CustomPropertyValueEditor.Storyboard)]
public Storyboard MouseLeaveStoryboard {
get { return (Storyboard)GetValue(MouseLeaveStoryboardProperty); }
set { SetValue(MouseLeaveStoryboardProperty, value); }
}

public static readonly DependencyProperty MouseLeaveStoryboardProperty =
DependencyProperty.Register("MouseLeaveStoryboard",
                        typeof(Storyboard),
                        typeof(HoverBehavior),
                        new PropertyMetadata(null, OnMouseLeaveStoryboardPropertyChanged));

private static void OnMouseLeaveStoryboardPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var owner = d as HoverBehavior;
if (owner != null) {
//TODO: Handle new value.
}
}

#endregion MouseLeaveStoryboard Dependency Property

Hook up the events:

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

AssociatedObject.MouseEnter += delegate {
MouseEnterStoryboard.Begin();
};
AssociatedObject.MouseLeave += delegate {
MouseLeaveStoryboard.Begin();
};
}

You should check if the Storyboards really exist but that’s not important for this example. Let’s build the project and drop a HoverBehavior on a UIElement:

hover

The interesting this is that we cannot choose a Storyboard from a dropdownlist.

no dropdown

Add CustomPropertyValueEditor attribute for better blend support

To provide a dropdownlist with available storyboards, add this attribute to the dependency properties:

[CustomPropertyValueEditor(CustomPropertyValueEditor.Storyboard)]
public Storyboard MouseEnterStoryboard {
get { return (Storyboard)GetValue(MouseEnterStoryboardProperty); }
set { SetValue(MouseEnterStoryboardProperty, value); }
}

[CustomPropertyValueEditor(CustomPropertyValueEditor.Storyboard)]
public Storyboard MouseLeaveStoryboard {
get { return (Storyboard)GetValue(MouseLeaveStoryboardProperty); }
set { SetValue(MouseLeaveStoryboardProperty, value); }
}

All available storyboards will show up in a dropdownlist:

dropdown

Written by Loek van den Ouweland on 2010-02-25.
Questions regarding this artice? You can send them to the address below.