views:

2126

answers:

3

Imagine you want to animate some object on a WinForm. You setup a timer to update the state or model, and override the paint event of the Form. But from there, what's the best way to continually repaint the Form for the animation?

  • Invalidate the Form as soon as you are done drawing?
  • Setup a second timer and invalidate the form on a regular interval?
  • Perhaps there is a common pattern for this thing?
  • Are there any useful .NET classes to help out?

Each time I need to do this I discover a new method with a new drawback. What are the experiences and recommendations from the SO community?

+1  A: 

What you're doing is the only solution I've ever used in WinForms (a timer with constant redrawings). There are a bunch of techniques that you can use to make the user's experience with it smoother (such as double-buffering).

You might want to give WPF a try. There are built-in facilities for doing animations in WPF, and they're much smoother (and require less code and no synchronization on your part) than a timer-based solution.

Note that you do not need to use WPF throughout your whole app for that solution; it's possible to pack this functionality into a WPF control and embed the control in a WinForms application (or an unmanaged app, for that matter):

http://www.codeproject.com/KB/WPF/WPF_UserControls.aspx

DannySmurf
+2  A: 

In some situations, it's faster and more convenient to not draw using the paint event, but getting the Graphics object from the control/form and painting "on" that. This may give some troubles with opacity/anti aliasing/text etc, but could be worth the trouble in terms of not having to repaint the whole shabang. Something along the lines of:

private void AnimationTimer_Tick(object sender, EventArgs args)
{
    // First paint background, like Clear(Control.Background), or by
    // painting an image you have previously buffered that was the background.
    animationControl.CreateGraphics().DrawImage(0, 0, animationImages[animationTick++)); 
}

I use this in some Cntrols myself, and have then buffered images to "clear" the bakground with when the object of interest moves or need to be removed.

Peteter
+8  A: 

I've created a library that might help with this. It's called Transitions, and can be found here: http://code.google.com/p/dot-net-transitions/

It uses timers running on a background thread to animate the objects. The library is open-source, so if it is any use to you, you can look at the code to see what it's doing.

Richard Shepherd
Awesome library. Nicely done and works great.
Ryan Farley
hey dude I did:`Transition.run(first, "Location.Y", first.Location.Y - 100, new TransitionType_Deceleration(500));`but I get an error saying that button does not have a property called Location.Y
Luiscencio
Awesome library, I love it. Reminds me of JQuery.UI
Malfist