
Introduction
This article demonstartes a simple gradient label control in C#.
Making the control
Open Visual Studio.NET and create a new project. Select Class Library and enter LabelGradient for the project name then click OK. Rename the Class1.cs file in solution explorer to LabelGradient.cs, and rename the default class and the constructor to LabelGradient.
Adding project references
In Solution Explorer, select LabelGradient, right click, choose Add Reference. The Add References dialog box opens. Select the .NET tab. Scroll down and highlight the System.Windows.Forms.dll then click select. Repeat the process for System.Drawing.dll, then click OK.
Now add the following namespaces to the code to save some typing.
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
I' am going to base the component around the Label class. To use the Label class as my base class, I must derive from it. To do this we change the default class definition from
public class LabelGradient
to
public class LabelGradient : Label
Note: The icon in solution explorer will automatically change.
Declare variables
protected Color gradientColorOne = Color.White;
protected Color gradientColorTwo = Color.Blue;
protected LinearGradientMode lgm = LinearGradientMode.ForwardDiagonal;
protected Border3DStyle b3dstyle = Border3DStyle.Bump;
The direction of the linear gradient, ForwardDiagonal specifies a gradient from upper left to lower right.
protected LinearGradientMode lgm = LinearGradientMode.ForwardDiagonal;
Properties
Take the description in the Property Browser window, under the category of Appearance and specify the default value for the property.
[DefaultValue(typeof(Color),"White"),
Description("The first gradient color."),
Category("Appearance"),
]
Now let's define our properties for GradientColorOne.
public Color GradientColorOne
{
get
{
return gradientColorOne;
}
set
{
gradientColorOne = value;
Invalidate();
}
}
The Invalidate() method invalidates the specified region of our control and causes a paint message to be sent to our control.
LinearGradientMode Properties
[
DefaultValue(typeof(LinearGradientMode),"ForwardDiagonal"),
Description("Gradient Mode"),
Category("Appearance"),
]
public LinearGradientMode GradientMode
{
get
{
return lgm;
}
set
{
lgm = value;
Invalidate();
}
}
Border3DStyle Properties
Note the use of the new modifier keyword in
new public Border3DStyle BorderStyle
This hides the BorderStyle property inherited from the base class.
To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.
[
DefaultValue(typeof(Border3DStyle),"Bump"),
Description("BorderStyle"),
Category("Appearance"),
]
new public Border3DStyle BorderStyle
{
get
{
return b3dstyle;
}
set
{
b3dstyle = value;
Invalidate();
}
}
Removing Unwanted Properties
The LabelGradient class inherited the default BackColor property, which we no longer wish to use. We can shadow the default BackColor by overriding it, allowing us to hide it.
The Browsable attribute set to false specifies that the property should not be displayed in the Property Browser window.
EditorBrowsable attribute set to EditorBrowsableState.Never hides the property of the control from intelliSense.
[
Browsable(false),
EditorBrowsable(EditorBrowsableState.Never)
]
public override System.Drawing.Color BackColor
{
get
{
return new System.Drawing.Color();
}
set {;}
}
Painting the control
All we need to do now is paint the control with the two gradient color's and tell it the direction of the linear gradient border style.
OnPaintBackground paints the background of the window and is guaranteed to be fast. While OnPaint paints the details and might be slower because individual paint requests are combined into one Paint event.
First we must override the OnPaintBackground method, then we create a graphics object, the PaintEventArgs specifies the graphics object used to paint the control.
Rectangle rect = new Rectangle (0,0,this.Width,this.Height)
draws our rectangle and LinearGradientBrush defines our brush fill. ControlPaint.DrawBorder3D method draws a three-dimensional style border around the control.
The using statement defines a scope at the end of which an object will be disposed as long as the object implements the System.IDisposable interface, as System.Drawing.Brush does. Thanks to Richard_D for the tip on the using statement.
gfx.FillRectangle(lgb,rect) fills our rectangle with our brush fill type. When overriding OnPaintBackground in a derived class, it is not necessary to call the base class's OnPaintBackground method as with OnPaint.
protected override void
OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
{
Graphics gfx = pevent.Graphics;
Rectangle rect = new Rectangle (0,0,this.Width,this.Height);
using (LinearGradientBrush lgb = new LinearGradientBrush(rect,
gradientColorOne,gradientColorTwo,lgm))
gfx.FillRectangle(lgb,rect);
ControlPaint.DrawBorder3D(gfx,rect,b3dstyle);
}
The Complete Code
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace LabelGradient
{
public class LabelGradient : Label
{
#region Implementtation Member Fields
protected Color gradientColorOne = Color.White;
protected Color gradientColorTwo = Color.Blue;
protected LinearGradientMode lgm =
LinearGradientMode.ForwardDiagonal;
protected Border3DStyle b3dstyle = Border3DStyle.Bump;
#endregion
#region GradientColorOne Properties
[
DefaultValue(typeof(Color),"White"),
System.ComponentModel.Description("The first gradient color."),
System.ComponentModel.Category("Appearance"),
]
public Color GradientColorOne
{
get
{
return gradientColorOne;
}
set
{
gradientColorOne = value;
Invalidate();
}
}
#endregion
#region GradientColorTwo Properties
[
DefaultValue(typeof(Color),"Blue"),
Description("The second gradient color."),
Category("Appearance"),
]
public Color GradientColorTwo
{
get
{
return gradientColorTwo;
}
set
{
gradientColorTwo = value;
Invalidate();
}
}
#endregion
#region LinearGradientMode Properties
[
DefaultValue(typeof(LinearGradientMode),"ForwardDiagonal"),
Description("Gradient Mode"),
Category("Appearance"),
]
public LinearGradientMode GradientMode
{
get
{
return lgm;
}
set
{
lgm = value;
Invalidate();
}
}
#endregion
#region Border3DStyle Properties
[
DefaultValue(typeof(Border3DStyle),"Bump"),
Description("BorderStyle"),
Category("Appearance"),
]
new public Border3DStyle BorderStyle
{
get
{
return b3dstyle;
}
set
{
b3dstyle = value;
Invalidate();
}
}
#endregion
#region Removed Properties
[
Browsable(false),
EditorBrowsable(EditorBrowsableState.Never)
]
public override System.Drawing.Color BackColor
{
get
{
return new System.Drawing.Color();
}
set {;}
}
#endregion
public LabelGradient()
{
}
protected override void
OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
{
Graphics gfx = pevent.Graphics;
Rectangle rect = new Rectangle (0,0,this.Width,this.Height);
using (LinearGradientBrush lgb = new
LinearGradientBrush(rect,
gradientColorOne,gradientColorTwo,lgm))
gfx.FillRectangle(lgb,rect);
ControlPaint.DrawBorder3D(gfx,rect,b3dstyle);
}
}
}
Testing the control
Right click on solution explorer and select Add New Project, the add new project dialog appears. Enter Demo for the name and click OK. Now drag the LabelGradient from the toolbox onto the form. Right click Demo in solution explorer and select Set as startup project. Now click Build solution from the build menu.