While reviewing The C# Top 100 it occurred to me that in my own code base I have many bits of code which may make useful blog posts, and that shouldn't take as long to write as the ones I usually create. Plus, I've a fair amount of source code for extending built in controls in various ways, creating new controls from scratch and other useful library code - I need to explore ways of decoupling some of that and releasing it for anyone to use.
To get started with this idea is a simple article on painting
animated images using C#. If you assign an animated GIF file to
Image property of a
Control, the .NET Framework will
take care of animating the image for you. However, it only
provides this automatically for the
Image property and not for
other properties such as
BackgroundImage, or any custom image
properties you add to your own components.
Fortunately the framework doesn't secret the animation
functionality away and provides the static
System.Drawing) to handle the bulk of the work.
(Image Credit: Dominique Toussaint)
The first thing to do is check if an animate can be animated.
While calling the various
ImageAnimator methods with static
images (or even
null references) won't crash, if your image is
static then there's no need to call them in the first place.
ImageAnimator.CanAnimate method takes a source
returns if it supports animation or not. Passing
null to this
method will also return
(Image Credit: Vera Kratochvil)
If your image supports animation, the next step is to call
ImageAnimator.Animate, passing in both the source image and an
EventHandler to receive change notifications.
This method will create a background thread that will periodically check watched images and advance frames as required. When it detects a new frame should be painted, it will call the event handler registered for the image, allowing you to handle the update, e.g. repaint your control.
Only one thread is created no matter how many images are being animated
One mistake I sometimes see developers do is calling the
Refreshmethod of a custom Windows Forms control. Calling
Refreshwill force the control and its children to be repainted immediately. An alternative way is to call
Invalidate(without any arguments) which will mark the window to be repainted without forcing the paint or repainting child windows - generally this is more suitable and reduces the number of unneeded repaints.
When you are finished with the source image, you should call
ImageAnimator.StopAnimate to remove the image and callback
from the list of watched images.
The current frame is part of the
Image instance's metadata, so
you don't need to do anything specific to paint animated images
vs static. With that said, the
ImageAnimator class tracks the
current frame separately and doesn't update the source
until requested, which you do by calling
As you can probably see, this is quite a simple process and
makes it easy to support animated graphics in applications that
A complete example demonstrating how to use the
class is available from the link below.
- 2017-10-28 - First published
- 2020-11-22 - Updated formatting
Like what you're reading? Perhaps you like to buy us a coffee?