Click here to Skip to main content
Click here to Skip to main content

WPF Animatable Button

, 11 Apr 2009
Rate this:
Please Sign up or sign in to vote.
A button that eliminates the need for triggers for defining button state chage storyboards.

Introduction

This article is about simplifying the process of defining button mouse over, pressed, enabled, and disabled animations. The process of defining triggers is quite complicated when you include all of the IsMouseOver, IsPressed, and IsEnabled states. You will also need to work hard and define BeginStoryboard/StopStoryboard precisely to make your desired animation start. Some of these states are overlapping. For instance, when the button is in the IsPressed state, most likely, it will be also in the IsMouseOver state and that leads to an improper animation to act. It is also quite annoying to define all these complex triggers every time for such a common problem.

Solution

I have defined a new control - AnimatableButton, which is inherited from the standard WPF Button. This new AnimatableButton listens to state changes of the button, looks for the corresponding animation, and runs it. All you need to do is to define Storyboards with predefined names - “NormalAnimation”, “MouseOverAnimation”, “PressedAnimation”, or “DisabledAnimation”. You may define them either in the resource dictionary of the button or the template. That is all you need to do. AnimatableButton will do the rest for you.

The logic for choosing which animation to run is inside the GetAnimationName method:

protected virtual string GetCurrentAnimationName()
{
   switch (State)
   {
      case ButtonState.Normal:
         return "NormalAnimation";
      case ButtonState.MouseOver:
         return "MouseOverAnimation";
      case ButtonState.Pressed:
         return "PressedAnimation";
      case ButtonState.Disabled:
         return "DisabledAnimation";
      default:
         return string.Empty;
   }
}

As you see, this method is virtual, which means that you may extend AnimatableButton and override its functionality. It will allow you to run animations based on the states other than IsMouseOver, IsPressed, and IsEnabled. You may also force the button to update its visual state by calling InvalidateAnimation(). The last one will run the animation based on the GetAnimationName method.

The button also exposes its State. Its an enumeration which has the values: Normal, MouseOver, Pressed, and Disabled. You may use it for your own needs.

Usage Example

Below is an example of a button which has a template and animations defined. Please notice that there are no triggers defined.

<common:AnimatableButton >
  <common:AnimatableButton.Style>
    <Style TargetType="{x:Type common:AnimatableButton}">
      <Style.Setters>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type common:AnimatableButton}">
              <Border>
                <Border.Background>
                  <SolidColorBrush x:Name="bg" />
                </Border.Background>
                <ContentPresenter />
              </Border>
              <ControlTemplate.Resources>
                <Storyboard x:Key="NormalAnimation">
                  <ColorAnimation To="Yellow" Duration="0:0:0.200" 
                    Storyboard.TargetName="bg" 
                    Storyboard.TargetProperty="Color" />
                </Storyboard>
                <Storyboard x:Key="MouseOverAnimation">
                  <ColorAnimation To="Red" Duration="0:0:0.200" 
                    Storyboard.TargetName="bg" 
                    Storyboard.TargetProperty="Color" />
                </Storyboard>
                <Storyboard x:Key="PressedAnimation">
                  <ColorAnimation To="Blue" Duration="0:0:0.200" 
                    Storyboard.TargetName="bg" 
                    Storyboard.TargetProperty="Color" />
                </Storyboard>
                <Storyboard x:Key="DisabledAnimation">
                  <ColorAnimation To="DarkGray" Duration="0:0:0.200" 
                    Storyboard.TargetName="bg" 
                    Storyboard.TargetProperty="Color" />
                </Storyboard>
              </ControlTemplate.Resources>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style.Setters>
    </Style>
  </common:AnimatableButton.Style>
</common:AnimatableButton>

Origin

The origin of this article can be found at WPF Animatable Button.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ruben Hakopian
Software Developer (Senior) Independent Contractor
United States United States

Comments and Discussions

 
GeneralThanks PinmemberDiandi13-May-09 14:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 11 Apr 2009
Article Copyright 2009 by Ruben Hakopian
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid