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