Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple animation in WinForms

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?

like image 496
Chris Smith Avatar asked Aug 14 '08 16:08

Chris Smith


3 Answers

I've created a library that might help with this. It's called Transitions, and can be found here: https://github.com/UweKeim/dot-net-transitions. Available on nuget as the dot-net-transitions package

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.

like image 185
Richard Shepherd Avatar answered Oct 11 '22 18:10

Richard Shepherd


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 Controls myself, and have buffered images to "clear" the background with, when the object of interest moves or need to be removed.

like image 29
Peteter Avatar answered Oct 11 '22 18:10

Peteter


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

like image 44
TheSmurf Avatar answered Oct 11 '22 16:10

TheSmurf