Click here to Skip to main content
15,881,715 members
Articles / Programming Languages / C#
Article

PictureBoxGradient UserControl

Rate me:
Please Sign up or sign in to vote.
3.25/5 (4 votes)
1 Nov 2002CPOL2 min read 125.4K   2.8K   49   23
Extended PictureBox with thin gradient progress line, out of the box straight forward Windows XP Look.

Sample Image - PictureBoxGradient.jpg

Introduction

My first article was based on a class which only draws the Gradient progress line. I guess there was too much work to use it. My idea was to drag a new control to my form, set the properties to what I like, and everything should work.

This new Control replaces the old version and is ready to use, extended by the most important properties from PictureBox and Gradient Class. It uses a Thread based Timer Class to redraw itself. With this timer it is possible to draw the Gradient while you're doing hard work behind the scenes.

How to use it

  • Drag PictureBoxGradient User Control from Toolbox to your form
  • Extend "PictureBox" Tab in "Property" Toolwindow, select a image
  • Extend "Gradient" Tab and choose colors to draws Gradient, e.g. Color1 white and Color2 orange
  • this.pictureBoxGradient1.Start()

and you're finished.

To use the gradient call Start and Stop

Key Benefits

  • MSDN styled Help File included, created with NDoc (great freeware).
  • Easy to use, no great library is used, just copy the UserControl to your code and change Namespace.
  • Easy customizable, every property can altered via Property ToolWindow.
  • Compact design, black boxed in only one control.
  • 100% C#, no API's used.

How it works

The User Control is based on a PictureBox in which SizeMode is set to AutoSize. The height property of PictureBox is extended by the GradientHeight Property. When you choose a Image the control resize itself to reflect changes made to the Image Property.

The Gradient is basically drawn with four LinearGradientBrush and two SolidBrush classes. mainRect is the Rectangle in which we have to draw. The Gradient will move from Position 0 to mainRect.Width.

The problem is that the Gradient will move out on the right side, and at the same time it will move in at the left side. It seems like the Gradient would cycle and never leave the Rectangle. Because of this we need four LinearGradientBrush and not only two. We need also two SolidBrush to fill the region which is not affected by the Gradient. These brushes are created with the two colors used for Gradient.

These Properties are important for drawing:

  • GradientHeight height of Gradient.
  • GradientSizeInProcent Gradient size in % relative to the given width.
  • Rectangle Gradient rectangle ( GradientHeight included ).
  • Color1 and Color2 used for LinearGradientBrush.
  • Step Stepsize in Pixel.
  • Speed Timer tick in milliseconds.
  • With this Propertys we can figure out how the Gradient must be drawn. The GradientSizeInProcent is evaluated like this:

    C#
    // get Gradient size n pixel from procent
    decimal factor = (decimal) mainRect_.Width / 100;
    GradientSize_ = (float) System.Math.Round( (decimal) 
             this.GradientSizeInProcent * factor);

    Every time the timer ticks, the Position will increased by Step till current Position + Step is greater than the given mainRect_.Width. In this case Position is set back to 0. The Gradient updates to reflect changes.

    C#
    //
    pos_ = pos_ + stepSize_;
    //
    if (pos_ > mainRect_.Width)
    {
        pos_ = 0;
    }
    PaintGardient();
    Initalize needed Rectangle with mainRect_
    C#
    //
    bool useRightBrush = false;
    bool useLeftBrush = false;
    //
    // init
    RectangleF rectLeft = mainRect_;
    RectangleF rectRight = mainRect_;
    RectangleF rectRightFill = mainRect_;
    RectangleF rectLeftFill = mainRect_;
    RectangleF rectRightLeftEnd = mainRect_;
    RectangleF rectRightRightEnd = mainRect_;    
    Get current position and evaluate Rectangles for each brush.
    C#
    //    create Gradient rects        
    rectLeft.Width =  gardientSize_;
    rectLeft.X = pos_ - rectLeft.Width;
    rectRight.X = mainRect_.X + pos_;
    rectRight.Width = gardientSize_;
    // create filler rects
    rectLeftFill.Width = pos_ - gardientSize_;
    rectRightFill.X = pos_ + gardientSize_;
    rectRightFill.Width = mainRect_.Width - (pos_ + gardientSize_);
    //
    if ((pos_ + gardientSize_) > mainRect_.Width)
    {
        rectRightRightEnd.X = - (mainRect_.Width - pos_);
        rectRightRightEnd.Width = gardientSize_;
        useRightBrush = true;
        //
        rectLeftFill.X = rectRightRightEnd.X + gardientSize_;
        rectLeftFill.Width -= rectRightRightEnd.X + gardientSize_;
    }        
    if (pos_ <= gardientSize_)
    {
        useLeftBrush = true;
        //
        rectRightLeftEnd.X = (mainRect_.Width - gardientSize_) + pos_;
        rectRightLeftEnd.Width = gardientSize_;
        //    
        rectRightFill.X = rectRight.X + gardientSize_;
        rectRightFill.Width = rectRightLeftEnd.X - rectRightFill.X;
    
    }
    Get LinearGradientBrush based on evaluated Rectangles.
    C#
    //create gardient brushes
    Brush brushLeft = new LinearGradientBrush(rectLeft,color1_, color2_,0,true);
    Brush brushRight = new LinearGradientBrush(rectRight,color2_, color1_,0,true);
    Brush brushLeft1 = new LinearGradientBrush(rectRightLeftEnd,color1_, color2_,0,true);
    Brush brushRight1 = new LinearGradientBrush(rectRightRightEnd,color2_, color1_,0,true);
    Last but not least draw current position of the Gradient.
    C#
    //
    graphics_.FillRectangle(new SolidBrush(color1_),rectLeftFill);
    //
    graphics_.FillRectangle(brushLeft,rectLeft);
    graphics_.FillRectangle(brushRight,rectRight);
    //
    graphics_.FillRectangle(new SolidBrush(color1_),rectRightFill);
    //
    if (useRightBrush)
    {
        graphics_.FillRectangle(brushRight1,rectRightRightEnd);
    }
                
    //
    if (useLeftBrush)
    {
        graphics_.FillRectangle(brushLeft1,rectRightLeftEnd);
    }

    Have phun with it...

    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)
    Switzerland Switzerland
    My interest is in the future because I am going to spend the rest of my life there. (Charles Kettering)

    Biography

    • 1996 - 1998 PC Board PPL, HTML, DHTML, Javascript and ASP
    • 1999 - 2001 coding Centura against Sql Database (SqlBase,MSSQL,Oracle)
    • 2002 - 2004 C# Windows Forms
    • 2005 - 2006 C# ASP.NET, Windows Forms
    • 2006 - 2009 C#, WCF, WF, WPF
    • 2010 - 2012 C#, Dynamics CRM, Sharepoint, Silverlight
    • 2013 - 2013 C#, WCF DS (OData), WF, WPF
    • 2014 - 2016 C#, Azure PaaS, Identity, OWIN, OData, Web Api
    • 2017 - now C#, aspnet.core, IdentityServer4, TypeScript & Angular @ Azure IaaS or PaaS

    Interests

    • family & friends
    • chilaxing ,)
    • coding

    Comments and Discussions

     
    GeneralLack of features Pin
    Miguel Lopes31-Aug-06 5:31
    Miguel Lopes31-Aug-06 5:31 
    AnswerRe: Lack of features Pin
    Chris Richner26-Nov-06 3:36
    Chris Richner26-Nov-06 3:36 
    GeneralDrawing of a gradient progress bar Pin
    skalkin10-Sep-04 14:51
    skalkin10-Sep-04 14:51 
    GeneralRe: Drawing of a gradient progress bar [modified] Pin
    Chris Richner10-Sep-04 17:59
    Chris Richner10-Sep-04 17:59 
    GeneralBoring Pin
    hakan.lambracht21-Jun-04 0:33
    hakan.lambracht21-Jun-04 0:33 
    GeneralRe: Boring Pin
    Anonymous8-Jul-05 1:34
    Anonymous8-Jul-05 1:34 
    AnswerRe: Boring Pin
    Chris Richner3-Oct-05 11:00
    Chris Richner3-Oct-05 11:00 
    Generalmemory leak Pin
    Member 12220924-Sep-03 8:56
    Member 12220924-Sep-03 8:56 
    GeneralRe: memory leak Pin
    Chris Richner25-Sep-03 4:43
    Chris Richner25-Sep-03 4:43 
    GeneralRe: memory leak Pin
    Member 12220925-Sep-03 11:33
    Member 12220925-Sep-03 11:33 
    GeneralRe: memory leak Pin
    Chris Richner26-Sep-03 4:15
    Chris Richner26-Sep-03 4:15 
    GeneralRe: memory leak Pin
    neilcawse29-Feb-04 10:15
    neilcawse29-Feb-04 10:15 
    GeneralRe: memory leak Pin
    Chris Richner29-Feb-04 10:43
    Chris Richner29-Feb-04 10:43 
    QuestionWhy Gardient? Pin
    Pete Bassett13-Oct-02 23:12
    Pete Bassett13-Oct-02 23:12 
    AnswerRe: Why Gardient? Pin
    Pete Bassett13-Oct-02 23:16
    Pete Bassett13-Oct-02 23:16 
    GeneralRe: Why Gardient? Pin
    Anonymous14-Oct-02 8:45
    Anonymous14-Oct-02 8:45 
    GeneralRe: Why Gardient? Pin
    Chris Richner14-Oct-02 12:27
    Chris Richner14-Oct-02 12:27 
    GeneralRe: Why Gardient? Pin
    Heath Stewart14-Jan-03 8:54
    protectorHeath Stewart14-Jan-03 8:54 
    QuestionMoving form suspends drawing, any hints ? Pin
    Chris Richner13-Oct-02 5:53
    Chris Richner13-Oct-02 5:53 
    AnswerRe: Moving form suspends drawing, any hints ? Pin
    Pete Bassett31-Oct-02 4:07
    Pete Bassett31-Oct-02 4:07 
    GeneralRe: Moving form suspends drawing, any hints ? Pin
    Chris Richner1-Nov-02 0:34
    Chris Richner1-Nov-02 0:34 
    GeneralRe: Moving form suspends drawing, any hints ? Pin
    Pete Bassett1-Nov-02 0:38
    Pete Bassett1-Nov-02 0:38 
    GeneralRe: Moving form suspends drawing, any hints ? Pin
    Chris Richner2-Nov-02 5:40
    Chris Richner2-Nov-02 5:40 

    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.