Click here to Skip to main content
15,888,461 members
Articles / Multimedia / GDI+
Article

A progress disk similar to that in SQL Server 2005

Rate me:
Please Sign up or sign in to vote.
3.71/5 (43 votes)
31 May 2007CPOL2 min read 115.2K   2.6K   105   30
The use of built-in methods of GDI+ to draw a progress disk similar to the one in SQL Server 2005

Sample screenshot

Introduction

Progress disk is a simple control that I wrote after I saw the one in SQL Server 2005. It can be used to replace the old progress bar with a nice and colorful mix of gradient colors.

Idea

The .NET 2.0 class library has the Graphics object, which is responsible for drawing 2D shapes. It has primitive shapes such as point, line, rectangle, ellipse, pie, etc. I used the DrawPie method to draw my control, which is formed by drawing 3 pie layers over top of each other:

  • The first layer in the bottom: a pie having a start angle of zero and a sweep angle of 360 degrees to draw a full circle that serves as the background of the control
  • The second layer in the middle: a pie that represent the blocks of the disk; 12 blocks (pie pieces) have been drawn, each having a sweep angle of 25 degrees and a separating angle of 5
  • The third layer in the top: similar to the first layer, but its function is to control the size of the blocks; the smaller the circle drawn, the bigger the blocks appear (i.e. having an inner circle with radius zero would give blocks having the shape of slices of a pizza)

Colors

I used a linear gradient brush to fill in the blocks: 2 colors for the inactive blocks and 2 for the active block. Properties added to keep the control flexible include:

  • Value: The current value of the progress disk
  • BackGroundColor: The color of the background
  • ActiveForeColor1 & ActiveForeColor2: These 2 for the block of current value
  • InactiveForeColor1 & ActiveForeColor2: These 2 for the rest of the blocks
  • SquareSize: The side length of the square containing the control
  • BlockSize: An enum for 6 different sizes
  • SliceNumber: The number of slices in the control (added by Coyotelapa)

Code

4 GraphicsPath objects were used to draw the control, one for each layer and an extra one to color the block with the current value.

C#
protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        region = new Region(ClientRectangle);
        if (backGrndColor == Color.Transparent)
        {
            region.Exclude(bkGroundPath2);
            Region = region;
        }

        e.Graphics.FillPath(new SolidBrush(backGrndColor), bkGroundPath1);
        e.Graphics.FillPath(
        new LinearGradientBrush(new Rectangle(0, 0, size, size),
            inactiveforeColor1, inactiveforeColor2,
        value * 360 / 12, true), valuePath);
        e.Graphics.FillPath(
        new LinearGradientBrush(new Rectangle(0, 0, size, size),
            activeforeColor1, activeforeColor2,
        value * 360 / 12, true), freGroundPath);
        e.Graphics.FillPath(new SolidBrush(backGrndColor), bkGroundPath2);

        base.OnPaint(e);
    }

//The Render method called on any change to control(size,colors,..)
private void Render()
    {

        bkGroundPath1.Reset();
        bkGroundPath2.Reset();
        valuePath.Reset();
        freGroundPath.Reset();
        bkGroundPath1.AddPie(new Rectangle(0, 0, size, size), 0, 360);

        //just in case...
        if (sliceCount == 0)
        {
            sliceCount = 12;
        }

        float sliceAngle = 360 / sliceCount;
        float sweepAngle = sliceAngle - 5;
        for (int i = 0; i < sliceCount; i++)
        {
            if (value != i)
            {
                valuePath.AddPie(0, 0, size, size, i * sliceAngle,
                    sweepAngle);
            }
        }
        bkGroundPath2.AddPie(
        (size / 2 - size * blockRatio), (size / 2 - size * blockRatio),
        (blockRatio * 2 * size), (blockRatio * 2 * size), 0, 360);
        freGroundPath.AddPie(new Rectangle(0, 0, size, size),
            value * sliceAngle, sweepAngle);
        Invalidate();
    }

History

  • 16 July, 2006 - Original version posted
  • 29 July, 2006 - Updated after adding improvements made by Coyotelapa and fixing some bugs
  • 31 May, 2007 - Article edited and moved to the main CodeProject.com article base

License

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


Written By
Software Developer (Senior)
Egypt Egypt

Amr is an iOS developer living in Cairo/Egypt.

Works now as Lead Software Engineer at ITWorx.

Main interests : iPhone/iPad/Mac app development.

Others :
Windows,GDI+,SqlServer, ASP.Net,Custom controls and others.

Academics:
BSc Computer and Information Sciences June 2006.

Certifications:
MCSD C#.Net
MCTS:SQL Server 2005

Blog: here

Comments and Discussions

 
GeneralMy vote of 5 Pin
Saumitra Kumar Paul9-Jul-11 22:39
Saumitra Kumar Paul9-Jul-11 22:39 
SuggestionUpdate Pin
Jayke Huempfner29-Jun-11 21:37
Jayke Huempfner29-Jun-11 21:37 
Hi there. Like coyotelapa, I also made some improvements and bug fixes to the code:

1. Placed a Timer within the user control allowing the progress disk to animate without needing to add a Timer to the form.
2. Added the Animate property to interact with the Timer. Animate is a boolean and when set to True, the Timer will be enabled and will run and raise Elapsed events. When set to False, the Timer will be disabled and the progress disk's value will stay the same.
3. Added the TimeDelay property to interact with the Timer. TimeDelay sets the amount of time, in milliseconds, before the Elapsed event is raised in the Timer, if the Timer is enabled.
4. Changed how the value changes when the Elapsed event is raised, thus allowing the progress disk to be animated without any bugs, mess-ups, or glitches with any number of slices. Before, because the constant 12 was used, if the SliceCount was anything different, certain slices would be skipped or repeated.
5. Organized the control's properties into categories, and added descriptions.
6. Updated the project to .NET Framework 4. The .cs files will still open in previous versions of Visual Studio though...

This is the first time I've worked with C#. I've been a VB.NET developer for years, but I decided it's time for me to move over to C#.

Overall, this is a very nice control. I'm happy to have come across it. With these refinements, I hope to make it even better.

I posted the new code on my website, rather than making a super-long message here: You can download the project here:
https://sites.google.com/site/jaykerh/ProgressDisk.zip?attredirects=0&d=1[^]
Jayke R. Huempfner

Yes, I do spell it with a 'y'...

AnswerProgressDisk whit IsIndeterminate Pin
Carlos Gutierrez29-Jan-09 5:07
Carlos Gutierrez29-Jan-09 5:07 
QuestionSlight clipping? Pin
mentatmatt25-Jun-08 4:07
mentatmatt25-Jun-08 4:07 
GeneralVery Nice Pin
Paul Conrad1-Jun-07 15:50
professionalPaul Conrad1-Jun-07 15:50 
GeneralRe: Very Nice Pin
Amr Elsehemy ®3-Jun-07 10:33
Amr Elsehemy ®3-Jun-07 10:33 
GeneralRe: Very Nice Pin
Paul Conrad3-Jun-07 15:06
professionalPaul Conrad3-Jun-07 15:06 
GeneralRe: Very Nice Pin
Amr Elsehemy ®1-Aug-07 0:57
Amr Elsehemy ®1-Aug-07 0:57 
GeneralCopyright Problem Pin
tylermenezes1-Aug-06 19:15
tylermenezes1-Aug-06 19:15 
GeneralRe: Copyright Problem Pin
Amr Elsehemy ®2-Aug-06 7:04
Amr Elsehemy ®2-Aug-06 7:04 
GeneralThis rocks! Pin
tylermenezes1-Aug-06 18:58
tylermenezes1-Aug-06 18:58 
GeneralRe: This rocks! Pin
Amr Elsehemy ®2-Aug-06 7:09
Amr Elsehemy ®2-Aug-06 7:09 
GeneralRe: This rocks! Pin
tylermenezes2-Aug-06 10:32
tylermenezes2-Aug-06 10:32 
GeneralBuilt-in timer Pin
AndrewRansom28-Jul-06 13:50
AndrewRansom28-Jul-06 13:50 
GeneralSliceCount Pin
Mc Gwyn27-Jul-06 23:39
Mc Gwyn27-Jul-06 23:39 
GeneralRe: SliceCount Pin
Aleksandar Lalic14-Aug-06 0:56
Aleksandar Lalic14-Aug-06 0:56 
GeneralBug Fixes / Improvements Pin
Aleksandar Lalic17-Jul-06 4:21
Aleksandar Lalic17-Jul-06 4:21 
GeneralRe: Bug Fixes / Improvements Pin
Amr Elsehemy ®18-Jul-06 13:56
Amr Elsehemy ®18-Jul-06 13:56 
GeneralRe: Bug Fixes / Improvements Pin
Aleksandar Lalic18-Jul-06 22:01
Aleksandar Lalic18-Jul-06 22:01 
GeneralResize problem Pin
tzvi16-Jul-06 8:38
tzvi16-Jul-06 8:38 
GeneralRe: Resize problem Pin
Amr Elsehemy ®16-Jul-06 13:10
Amr Elsehemy ®16-Jul-06 13:10 
GeneralTip Pin
leppie16-Jul-06 7:00
leppie16-Jul-06 7:00 
GeneralRe: Tip Pin
Amr Elsehemy ®16-Jul-06 7:10
Amr Elsehemy ®16-Jul-06 7:10 
GeneralA bug... Pin
Stanciu Vlad16-Jul-06 6:35
Stanciu Vlad16-Jul-06 6:35 
GeneralRe: A bug... Pin
Amr Elsehemy ®16-Jul-06 6:49
Amr Elsehemy ®16-Jul-06 6:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.