Introduction
When I started to develop web-services, I examined the possibility to display current activity. For example, when an application is loading something from the Internet, you can show a sandy-glass or a progress bar. The progress bar is not good enough because the application does not know its real status: how much was loaded and how much is left. Sure, you can write an asynchronous monitor for getting real status but it heavily loads your web-service. Anyway, I wish I had a simple animation control to show animated icons on the StatusBar
or wherever.
You know, there is an ImageAnimator
class in the .NET Framework Library that displays animated GIF files. It doesn't suit me because:
- I want to compose an animation from bitmaps during design time.
- I would like to set speed for the animation.
That's why I wrote a small and simple control.
Inside the code
AnimatedIcon
is a UserControl
with a few properties and methods. Have a look at this class (some private members are hidden):
Properties
Five properties define the look and behavior of the control:
ImageList
ImageList
contains images used to display the animation.
Delay
Delay in milliseconds between the frames. Default value is 50 ms.
Pause
Pause in milliseconds after every loop. Default value is 0.
LoopCount
Number of loops to display. Default value is 0. It means infinite loop.
FirstFrame
The first frame of the animation.
LastFrame
The last frame of the animation.
The Pause
property can be used to set a delay at the end of the loop (thank you, Tim, for the idea). FirstFrame
and LastFrame
are set to 0 and ImageList.Images.Count-1
respectively, by default. But you can set another range of frames for the animation. For example, if you added images to the ImageList
to display some special state of the object or even yet another animation.
Methods
The methods are quite self explaining:
Code
StartAnimation
creates a Thread
that is responsible for the logic of the control. StopAnimation
terminates this thread. threadFunc
counts the frames and sends a signal to redraw the frame when it is changed.
public void StartAnimation()
{
StopAnimation();
CheckRange();
thread = new Thread( new ThreadStart( threadFunc ) );
thread.IsBackground = true;
thread.Start();
}
public void StopAnimation()
{
if( thread != null )
{
thread.Abort();
thread = null;
}
currentLoop = 0;
}
public void ShowFrame(int frame)
{
StopAnimation();
if( frame >= 0 && imageList != null
&& frame < imageList.Images.Count )
currentFrame = frame;
else
currentFrame = 0;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
if( imageList == null ||
currentFrame < 0 ||
currentFrame >= imageList.Images.Count )
{
if( this.Size.Width == 0 || this.Size.Height == 0 )
return;
Pen pen = new Pen( SystemColors.ControlText );
e.Graphics.DrawRectangle( pen, 0, 0,
this.Size.Width-1, this.Size.Height-1 );
e.Graphics.DrawLine( pen, 0, 0,
this.Size.Width, this.Size.Height );
e.Graphics.DrawLine( pen, 0,
this.Size.Height-1, this.Size.Width-1, 0 );
pen.Dispose();
}
else
{
e.Graphics.DrawImage( imageList.Images[currentFrame],
0, 0, this.Size.Width, this.Size.Height );
}
}
private void threadFunc()
{
bool wasPause = false;
currentFrame = firstFrame;
while( thread != null && thread.IsAlive )
{
Refresh();
wasPause = false;
if( imageList != null )
{
currentFrame++;
if( currentFrame > lastFrame ||
currentFrame >= imageList.Images.Count )
{
if( pause > 0 )
{
Thread.Sleep( pause );
wasPause = true;
}
currentFrame = firstFrame;
if( loopCount != 0 )
{
currentLoop++;
}
}
if( loopCount != 0 && currentLoop >= loopCount )
{
StopAnimation();
}
}
if( !wasPause )
Thread.Sleep( delayInterval );
}
}
Using the AnimatedIcon
First of all, you should add the AnimatedIcon
control to the Toolbox in your Visual Studio .NET IDE. To do that, you should:
- Right-click on the "Windows Forms" tab in the Toolbox.
- Select "Add/Remove Items...".
- On ".NET Framework Components", press the "Browse..." button, and find the AnimatedIcon.dll.
New AnimatedIcon
control will be added to the Toolbox:
Now, you can drag this control from the Toolbox to your Form
. That will create a new AnimatedIcon
object in your project. By default, its ImageList
is empty, and the control is displayed as a crossed square. Select this object and modify its properties: set the ImageList
that contains a sequence of frames, set delay and the loop counter.
Don't forget to call the StartAnimation()
method somewhere. Compile your project and enjoy!
AnimatedIcon on the StatusBar
If you run my demo, you will see a small animated icon on the StatusBar
. I'll tell you how to do that. It cannot be done in the Designer, but it's very easy to do manually. First, create a private member in your Form
class:
private AnimatedIcon.AnimatedIcon animatedIcon2;
Then add a few lines to the constructor of the Form
:
public Form1()
{
InitializeComponent();
this.animatedIcon2 = new AnimatedIcon.AnimatedIcon();
this.animatedIcon2.Delay = 200;
this.animatedIcon2.ImageList = this.imageList2;
this.animatedIcon2.Name = "animatedIcon2";
this.animatedIcon2.TabStop = false;
this.animatedIcon2.Location = new Point(190,
(statusBar1.Height - animatedIcon2.Size.Height)/2);
statusBar1.Controls.Add(this.animatedIcon2);
this.animatedIcon2.StartAnimation();
}
This code adds the AnimatedIcon
object to the collection of controls contained within the StatusBar
. Note, my StatusBarPanel
with the text "Yet another..." is 180 units wide. That's why the left corner of the this.animatedIcon2
is 190 units:
this.animatedIcon2.Location = new Point(190,
(statusBar1.Height - animatedIcon2.Size.Height)/2);
I hope it was not difficult. Have a nice animation!
History
- June 18, 2004 - First release.
- June 28, 2004 - Version 1.1.