Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple Yet Extensible Animation Framework for Windows Forms

0.00/5 (No votes)
23 Nov 2011 1  
WPF has built in support for animating properties, this article demonstrates the same in Windows Forms.
Preview.png

Introduction

Just the wows of built in features of a WPF noob makes the purpose of this article. WPF has features as many as possible, which we used to take much more time to code in Windows Forms. One of the many key features of WPF is that it supports animating dependency properties.

This article demonstrates the concept and a simple yet extensible Animation framework for Windows Forms.

Check out the article Carousel Control for Windows Forms built over this animation framework. :)

Background

This project implements a generic interface that defines an Animation type, and invokes the animation on the target property using reflection.

It makes your work simple, animating the width of a button is as simple as in WPF! You can do wonders by animating some simple little things!!

IntAnimation widthAnimation =
                new IntAnimation
{
    AutoReset = true,
    AutoReverse = true,
    From = 100,
    To = 250,
    By = 1,
    Interval = 10,
    Duration = 3000
};

this.button1.Animate<int>("Width", widthAnimation);

Isn't this simple enough? Read on to know how!!

Using the Code

IAnimation<T> Interface

  • IAnimation<T> interface implements the following fields, which represents the information required for animating a property. Type T marks the type of target property the animation handles. For instance, to animate Width of a Control, the type will be integer.
  • AutoReset: If set to true, animation will commence again when completed.
  • AutoReverse: If set to true, animation will happen in reverse direction once it's completed. When both AutoReset and AutoReverse are set to true, animation will happen forth and back endlessly.
  • Interval: The time span between the successive value changes.
  • Duration: The time to run the animation. (Note: When range of values and duration is known, interval between successive updates can be calculated in Animation implementation as an alternative.)
  • By: The value by which the target property is updated.
  • From: The value from which the animation will bring.
  • To: The value at which the animation completes.
  • GetNewValue(int delta): Provides the next successive value for update.
/// <summary>
/// Defines IAnimation interface.
/// </summary>
/// <typeparam name="T">the type Animation is applied to</typeparam>
public interface IAnimation<T>
{
    bool AutoReset { get; set; }

    bool AutoReverse { get; set; }

    int Interval { get; set; }

    int Duration { get; set; }

    T By { get; set; }
        
    T From { get; set; }

    T To { get; set; }

    T GetNewValue(int delta);

    event AnimationEventHandler<T> Completed;

    event AnimationEventHandler<T> Started;

    event AnimationEventHandler<T> Freezed;
}

Animator

Animator defines static extension methods to invoke animation on the target property. and here is how it works.

#1. Gets the PropertyInfo of the target object by its name.

/// <summary>
/// Gets the PropertyInfo of specified type on the target object.
/// </summary>
/// <param name="target" />the target object.
/// <param name="property" />the name of the property.
/// <param name="t" />the return type of the property.
/// <returns>the property info if found, null otherwise.</returns>
private static PropertyInfo GetPInfo(object target, string property, Type t)
{
    if (t == null || target == null || String.IsNullOrEmpty(property))
        return null;

    return target.GetType().GetProperty(property, t);
}

#2. Sets the updated value on the target property.

pinfo.SetValue(target, newValue, null);

Actual work goes inside the static extension method Animator.Animate() this consumes the target object, the name of the property and the instance of animation type which holds the information about the type and values.

There are two timers running inside the Animator, one updates the value on the target property on specific interval and the other updates the status of the animator.

/**** truncated for clarity ****/

animSteps.Tick += (_, __) =>
        {
            T newValue = animation.GetNewValue(++delta);
            pinfo.SetValue(target, newValue, null);
        }
    };

    animDuration.Elapsed += (_, __) =>
        {
            if (!state.IsFreezed)
            {
                delta = -1;
                state.IsReversed = animation.AutoReverse ? !state.IsReversed : false;
            }

            if (!animSteps.Enabled && !animDuration.Enabled)
                state.RaiseCompleted(target);
        };

Points of Interest

This is a generic implementation and it can be used to animate any public property of any target type. The source includes the implementation for types Int and double.

History

  • First post - 2nd October, 2011
  • Few editorial revisions - 3rd October, 2011
  • New sample added for advanced usage pattern - 4th October 2011

Hope this will help reduce a lot of time writing codes for animating. Be sure to leave your comments and suggestions!.

Happy coding!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here