PictureBoxGradient UserControl






3.25/5 (4 votes)
Extended PictureBox with thin gradient progress line, out of the box straight forward Windows XP Look.
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 aPictureBox
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:
// 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.
//
pos_ = pos_ + stepSize_;
//
if (pos_ > mainRect_.Width)
{
pos_ = 0;
}
PaintGardient();
Initalize needed Rectangle
with mainRect_
//
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.
// 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
.
//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.
//
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...