Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

An animated progressbar control with many extras

4.95/5 (85 votes)
20 Nov 2006CPOL8 min read 1   39.7K  
An extended picturebox, animated picturebox, and an animated progressbar in one component.

Sample Image - Screenshot.png

Contents

Introduction

The idea for this component came to me while viewing the Iconits article[^]. The idea was really good, and while hovering over the icons from left to right, an idea came to me that this could make a great progress bar. Also, I missed some functionality and customizations, and because I already have a fully working component for animations (Animating Windows Forms[^]), I decided to build my own component.

Background

To fully understand the code, you will need knowledge about Windows Forms, Timers, designer support, and much more. I will not describe everything in detail. Have a look at the References for articles describing parts of my implementations in detail. On my way to the final progress bar control, I implemented several helping controls built on top of each other, which helped me to separate the whole big problem into smaller pieces. Doing so should be in the back of the head of every developer. It not only helps to keep classes small, and thus not to lose overview, but in this case, it also led to some controls which can also be used separately outside of the actual progress bar.

Using the code

Usage is very straightforward. There is a total of four controls which can all be used by just dragging them onto a Form with the designer. Nearly everything can be customized by using the designer, so just start exploring.

Samples

I have put much effort in supplying good samples in the downloads. They cover most of the functionality of this component, so if you want to know what the different controls are capable of, then play around with them. The downloads are primarily so big because of the images contained in the samples. The component itself is rather small.

Architecture

As already stated, I will not go into the details here, but will just describe how the classes are related to each other. Everything is well documented, and a help file is also included as a programmer's reference.

ExtendedPictureBox

Image 2

This control is somehow similar to the PictureBox class. At least, both have the common functionality of showing an Image. It has properties for applying alpha, rotation, gradient back colors, and some more. Furthermore, it has a property BaseSizeMode which handles, together with the Zoom property, how the shown Image is resized. Finally, it has the capability to show a second Image without alpha blending and resizing, with customizable rotation and alignment.

Some of those properties can not only be accessed or set separately, but also modified with the State property. This one doesn't have a real benefit within this control but contains all the properties which will get animated in later stages.

Its functionality is demonstrated in the top left sample of the main form in the sample application.

AnimatedPictureBox

Image 3

This class is derived from the ExtendedPictureBox. It uses my animation component, and thus for every animated property, I have implemented an animator class and an animator which bind them all together (everything can be found in the Animators sub namespace). The main extension is the Animate function which gets a new State object. Calling it will result in a smooth animation from the current to the new State. Furthermore, it has several properties, functions, and events to control the animation.

AnimatedPictureButton

Image 4

This one is actually not required for the progress bar but I nevertheless implemented it. It derives from AnimatedPictureBox and now holds two States: StartState and EndState. The first one will be displayed when the mouse cursor is not located over the control. When the mouse enters the control, it will animate its state into the second one.

The bottom left sample shows this one. Don't forget to click the button at the bottom right of the upcoming form which has some more predefined samples. Also notice that the sample selector is built with this control.

AnimatedPicturesProgressBar

Image 5

Finally, we are coming to the actual aim of this component. The AnimatedPicturesProgressBar has a Steps property where ProgressSteps describing the visual appearance of every step of the progress bar can be added. For every step, an AnimatedPictureBox is created and placed horizontally one after the other in the control. You can define a total of three states representing steps which are not yet started, in progress, or finished. Furthermore, you can define if and how the current step gets a little extra animation, and some more properties influencing the animations. After adding all the steps and setting all the properties, a call to EndInit is required (the designer will do this for you if you configure the progress bar completely with it), and if it's the second run, also to Reset. Then, for each starting step, a call to NextStep will advance the progress by one step. It is important to understand that if the main thread is blocked with some heavy operation, the animation won't show up (like any other repainting in the GUI). There are several ways to avoid this:

  • Do the processing in a separate thread. Don't forget to use Invoke to delegate the call to NextStep over the thread boundaries. This is the best way to keep the animations smooth without any heavy performance penalty.
  • Set the BlockNextStepCall to true. This way, the call to NextStep will return after the transition is completed. The performance might reduce a bit because your processing will be stopped while the animation is going on, and the rotation of the little extra image and the back color transition while a step is being processed won't be visible.
  • Ensure by yourself the control is being repainted. This can be done either by calling Refresh or Application.DoEvents. Keep in mind that calling these too often might result in a severe performance penalty, and calling them not often enough will result in a not very smooth or slowed down animation. Thus, I recommend using one of the other two solutions above.

Have a look at the bottom right sample. It shows all the combinations possible.

Memory Consumption

Just a small note on the memory consumption before everyone starts complaining that the component is allocating too much memory: This is totally normal! As you can imagine, much drawing logic is needed in this component. I also create in-memory bitmaps to ease this. Surely, this encourages the CLR to allocate much memory but it will also release it at regular intervals. Sure, I could force the garbage collector to do its work and dispose explicitly more often, but this is something not necessary in a managed environment and it could even reduce performance.

References

Several articles helped me with the implementations details. The most important ones are:

ToDo's

  • Some performance tweaking here and there should still be possible (although I did my best to make it fast).
  • I'm eager to extend this component with useful features requested here. So, if anyone has further suggestions, please feel free to post them here.

History

  • May 13th, 2006 - Version 1.0.0
    • Initial release.
  • July 1st, 2006 - Version 1.1.0
    • The AnimatedPictureButton will no longer react on mouse entering when it's disabled or if the container Form is not active.
    • Added support for transparent back colors for the ExtendedPictureBox and all derived controls. Both colors can have an alpha value. The only limitation is that the BackColor must have an alpha value smaller than 255 in order for this to work. Only setting the alpha on BackColor2 won't have any effect. Note that enabling transparency might greatly reduce performance (depending on what is painted beneath the control).

      I also enhanced some of the samples to test this out.

    • When the ExtendedPictureBox or any derived control is disabled, the images will now paint accordingly. I also added a new property AllowDisabledPainting to turn off this new functionality.
  • July 15th, 2006 - Version 1.2.0
    • Added support to display text in all four controls. The animated controls can animate the size, rotation, halo width, halo color, and fore color. This feature also supports the alignment of the text. Have a look at the samples - this adds some really cool effects.
    • Because of this, some constructors have changed and will probably confuse the designer. This should only hurt if you have defined steps for the AnimatedProgressBar within the designer. Please correct those errors by hand.
    • The ForeColor changed the color of the border in version 1.1.0. Now it changes the color of the text. The color of the border can now be adjusted by the new property BorderColor.
    • Changed the Editor of all my properties of type Color, which allows to set alpha values on the colors within the editor. Look here[^] for details regarding this.
  • November 18th, 2006 - Version 1.3.0
    • Added shadow effect for the images.
    • Added a total of three offset properties which enhances visualization and animation effects.
    • The AnimatedPictureButton reacts on mouse clicks to give the user a visual feedback that he hit the button.
    • Several other minor changes and fixes.
    • Changed the samples to reflect those changes. Because the sample forms where getting too big, I replaced the normal TrackBar with the one from NicolNghia which is smaller. You can find the control in his article: Advanced TrackBar (Slider) Control with MAC Style (C# and VB.NET)[^].

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)