![]() |
Desktop Development »
Miscellaneous »
Miscellaneous Controls
Intermediate
AnimatedIcon ControlBy Eugene PankovAnimatedIcon Control plays an animation as a sequence of images stored in the ImageList. The article demonstrates how to show an animated icon on the StatusBar. |
C#.NET 1.1, Win2K, WinXPVS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
![]()
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:
That's why I wrote a small and simple control.
AnimatedIcon is a UserControl with a few properties and methods. Have a look at this class (some private members are hidden):
![]()
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.
The methods are quite self explaining:
StartAnimation
Starts animation from the beginning.
StopAnimation
Stops animation.
ShowFrame
Stops animation and displays the specified frame.
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.
// Starts animation from the beginning.
public void StartAnimation()
{
StopAnimation();
CheckRange(); // Check the first and the last frames
thread = new Thread( new ThreadStart( threadFunc ) );
thread.IsBackground = true;
thread.Start();
}
// Stops animation not changing current frame number.
public void StopAnimation()
{
if( thread != null )
{
thread.Abort();
thread = null;
}
currentLoop = 0;
}
// Displays the specified frame.
public void ShowFrame(int frame)
{
StopAnimation();
if( frame >= 0 && imageList != null
&& frame < imageList.Images.Count )
currentFrame = frame;
else
currentFrame = 0;
Refresh();
}
// Occurs when the control is redrawn.
protected override void OnPaint(PaintEventArgs e)
{
// Draw a crossed rectangle if there is no frame to display
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
{
// Draw the current frame
e.Graphics.DrawImage( imageList.Images[currentFrame],
0, 0, this.Size.Width, this.Size.Height );
}
}
// The method to be invoked when the thread begins executing.
private void threadFunc()
{
bool wasPause = false;
currentFrame = firstFrame;
while( thread != null && thread.IsAlive )
{
Refresh(); // Redraw the current frame
wasPause = false;
if( imageList != null )
{
currentFrame++;
if( currentFrame > lastFrame ||
currentFrame >= imageList.Images.Count )
{
if( pause > 0 ) // Sleep after every loop
{
Thread.Sleep( pause );
wasPause = true;
}
currentFrame = firstFrame;
if( loopCount != 0 ) // 0 is infinitive loop
{
currentLoop++;
}
}
if( loopCount != 0 && currentLoop >= loopCount )
{
StopAnimation(); // The loop is completed
}
}
if( !wasPause ) // That prevents summation (pause + delayInterval)
Thread.Sleep( delayInterval );
}
}
First of all, you should add the AnimatedIcon control to the Toolbox in your Visual Studio .NET IDE. To do that, you should:
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!
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 code adds the AnimatedIcon to the StatusBar
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!
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 29 Jun 2004 Editor: Nishant Sivakumar |
Copyright 2004 by Eugene Pankov Everything else Copyright © CodeProject, 1999-2009 Web15 | Advertise on the Code Project |