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?
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?
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With