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
the 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 ImageAnimator
class
(located in System.Drawing
) to handle the bulk of the work.
(Image Credit: Dominique Toussaint)
Checking if an image can be animated
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.
The ImageAnimator.CanAnimate
method takes a source Image
and
returns if it supports animation or not. Passing null
to this
method will also return false
.
(Image Credit: Vera Kratochvil)
Preparing for animation
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
Refresh
method of a custom Windows Forms control. CallingRefresh
will force the control and its children to be repainted immediately. An alternative way is to callInvalidate
(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.
Halting animation
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.
Painting the image
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 Image
until requested, which you do by calling
ImageAnimator.UpdateFrames
.
Wrapping up
As you can probably see, this is quite a simple process and
makes it easy to support animated graphics in applications that
reference System.Drawing
.
A complete example demonstrating how to use the ImageAnimator
class is available from the link below.
Update History
- 2017-10-28 - First published
- 2020-11-22 - Updated formatting
Like what you're reading? Perhaps you like to buy us a coffee?