Creating a C# Gradient Progressbar Component

Sometimes, a normal control just isn’t enough, or sometimes you may want to extend the already existing functionality of a control; or perhaps, you simply want to make your own control. For all these reasons, I will demonstrate how to create your own Progressbar-like control that exposes the same properties as a normal Progressbar, but with added visual appeal.

What Precisely Is a Component?

To best explain the term Component, let me quote MSDN:

“The term component in the software industry is often used to refer to a reusable object that exposes one or more interfaces to clients in a standardized way. A component may be implemented as a single class, or as a set of classes; the primary requirement is that the basic public interface be well-defined.

“Some of the most commonly used components in .NET Framework programming are the visual controls that you add to Windows Forms such as the Button Control (Windows Forms), ComboBox Control (Windows Forms), and so on. Non-visual components include the Timer Control, SerialPort, and ServiceController, among others.”

Sounds simple enough, so how do you get started? Just follow these steps:

  1. Fire up Visual Studio .NET 2003.
  2. Click File, New, Project.
  3. Select Visual C# Projects from the Project Types list.
  4. Select Windows Control Library from the Templates list.
  5. Give a descriptive name, such as GradProg.
  6. Select OK.

This will produce the design window of a UserControl. This will be the base of your component. This will be your component.

Designing Your Interface

The design is actually quite simple. You don’t need much because you’ll be using the UserControl itself as the Progressbar. All you need to add to the UserControl is one label, and obviously, you need to set some basic properties for both the UserControl and the Label.

Set the following properties for the UserControl:

Property Value
Name GradProg
BackColor White
Width 150
Height 48

Add one label to your UserControl (if you haven’t done so already), and set the following properties for the Label:

Property Value
Name lblPerc
AutoSize True
BackColor White
Text 0%

Your design should now look something similar to what’s shown in Figure 1.

Figure 1: The design of your Gradient Progressbar

Coding

Before you jump in and code, you need a plan of action. First, you need to create a Progressbar; in doing that, you need to supply all the needed methods and logic to increment the bar, you will need to implement some Resizing logic, and finally, disposal of your bar. Secondly—this is where the fun comes in—you need to supply your own Properties and Methods to set the various Background Foreground colours, you need to implement the Gradient Style, and you need to make sure your limits (Maximum and Minimum) don’t go out of bounds.

Without further ado, it’s time to get started!

The Needed Namespaces

Open the Code Window for GradProg, and make sure you have the following using statements at the top:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

These Namespaces are needed mainly for the usage of several Drawing methods you are going to use.

The Needed Variables

You will need to remember your Property values; so, you need to create variables to store their particular values, as well as to set up each Property’s default value.

Add the following variables to your code, just above the Class Constructor:

private int Mini    = 0;    //Default Minimum Value
private int Maxi    = 100;  //Default Maximum Value
private int CurrVal = 0;    //Current Value
private int Percent = 0;    //Percentage

//ProgressBar Fore Colour
private Color BarForeColour = Color.LightSeaGreen;
//ProgressBar Back Colour
private Color BarBackColour = Color.DimGray;
//Label Fore Colour
private Color LabForeColour = Color.LightSeaGreen;
//Label Back Colour
private Color LabBackColour = Color.DimGray;

//Default Gradient Mode
private LinearGradientMode GradMode =
   LinearGradientMode.ForwardDiagonal;

private bool DispLabl = true;    //Show Label?
//Label To Display Progress
private System.Windows.Forms.Label lblPerc;

private Point LabPos;            //Label Position

As you can see with the above code, you have created variables to set up each property; you are going to use the default values. You have variables for the Minimum and Maximum values, the Label’s and Progressbar’s Fore- and Back Colours, the Gradient mode, as well as the Label’s position.

Building the Bar, Block by Block

If you have ever seen how a normal progressbar works, you will understand when I say the bar gets built block by block, until it reaches its limit. With your component, you don’t really need to display blocks; you want a smooth bar. But still, you need to update the display little by little with each increment of your counter. You achieve this with a method named SetProgComplete and the Value property. With each progression of the bar, you need to create a new Rectangle for the display of the bar’s value—not the numbered value, but the graphical value. Create a new method named SetProgComplete, and supply a Integer parameter named percentage; this will act as your incrementation value.

Your method should look like the following:

/// <summary>
/// Displays Current Progress
/// </summary>
/// <param name="percentage"></param>
public void SetProgComplete(int percentage)
{
   //Calculate New Width
   int Width = (int)Math.Floor((this.ClientRectangle.Width *
      percentage) / 100);
   //Calculate New Height
   int Height = (int)this.ClientRectangle.Height;

   if (Width > 0 && Height > 0)    //If Height And Width Valid
   {
      //Paint New Rectangle
      this.Invalidate(new Rectangle(this.ClientRectangle.X,
         this.ClientRectangle.Y, Width, Height));

      //Display Current Progress
      lblPerc.Text = Percent.ToString() + "%";
   }

}

The Value Property works hand in hand with your SetProgComplete property. As the bar progresses, a new Rectangle gets created where the previous one ended, thus creating each progression block.

/// <summary>
/// Sets Current Value & Updates Display
/// </summary>
public int Value
{
   get
   {
      return CurrVal;    //Get Value
   }

   set
   {
      int OldVal = CurrVal;    //Store Previous Value

      //Keep In Specified Range
      if ((value < Mini))
      {
         CurrVal = Mini;
      }
      else if ((value > Maxi))
      {
         CurrVal = Maxi;
      }
      else
      {
         CurrVal = value;
      }

      //Invalidate Changed Area Only
      int CurrPercent;

      Rectangle NewValRect = this.ClientRectangle;
      Rectangle OldValRect = this.ClientRectangle;

      //New Value To Calculate New Rectangle
      CurrPercent = (CurrVal - Mini) / (Maxi - Mini);
      NewValRect.Width = (NewValRect.Width * CurrPercent);

      //Old Value For Previous Rectangle
      CurrPercent = (OldVal - Mini) / (Maxi - Mini);
      OldValRect.Width = OldValRect.Width * CurrPercent;

      Rectangle UpdatedRect = new Rectangle();

      // Find only the part of the screen that must be updated.
      if ((NewValRect.Width > OldValRect.Width))
      {
         UpdatedRect.X = OldValRect.Size.Width;
         UpdatedRect.Width = NewValRect.Width - OldValRect.Width;
      }
      else
      {
         UpdatedRect.X = NewValRect.Size.Width;
         UpdatedRect.Width = OldValRect.Width - NewValRect.Width;
      }

      UpdatedRect.Height = this.Height;

      //Repaint Intersection
      this.Invalidate(UpdatedRect);
   }
}

More by Author

Must Read