Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article introduces you to custom controls and describes how they're different from user controls. Custom controls don't provide a visual design surface and rely on user-supplied code to draw themselves. This is different from user controls which provide a visual design surface to group multiple controls into a single reusable unit.
Custom controls are used when an existing control or user control doesn't come close to providing the UI or interactivity that you require. They require more effort on your part to fully implement. Keyboard and mouse handling is still provided by Windows Forms, but any behaviors are left up to you to implement. There isn't a design surface provided with a custom control, because all drawing is done through code in the OnPaint method. Components, such as a Timer, can still be added through the nonvisual design surface.
Base class
There are two base classes to choose from when creating a custom control:
-
This is the same base class used by other Windows Forms controls. You control the input and output of the control directly.
System.Windows.Forms.ScrollableControl
Some Windows Forms controls use this base class. This class extends
Control
by adding the ability to scroll the content.
Unless you require scrolling the contents of the custom control, use Control
as your base class.
Inherited capabilities
Since the base class of a custom control is Control, you automatically inherit Windows Forms functionality shared by all controls. Here are a few of the capabilities you get with a custom control:
- Keyboard and mouse input.
- Layout behaviors, such as anchoring and docking.
- Support for tabbing.
- Minimum and maximum size restrictions.
Painting
Painting, which means to draw the control's visual, is accomplished by overriding the OnPaint method. For more information about how controls do painting, see Painting and drawing on controls.
When you create a custom control using the Visual Studio templates, the OnPaint
method is automatically overridden for you. The template does this because you're required to write the code to draw your control. Here's an example of what the template generates:
public partial class CustomControl1 : Control
{
public CustomControl1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
}
Public Class CustomControl1
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
'Add your custom paint code here
End Sub
End Class
A custom control is painted with the OnPaint method. The single argument of this method is a PaintEventArgs object, which provides all of the information and functionality required to render your control. PaintEventArgs
provides two properties that are used in rendering your control:
PaintEventArgs.ClipRectangle—Represents the part of the control that needs to be redrawn. This can be the entire control or part of the control.
Graphics—Represents the graphical surface of your control. It provides several graphics-oriented objects and methods that provide the functionality necessary to draw your control.
The OnPaint
method is called whenever the control is drawn or refreshed on the screen, and the PaintEventArgs.ClipRectangle
object represents the rectangle in which painting takes place. If the entire control needs to be refreshed, PaintEventArgs.ClipRectangle
represents the size of the entire control. If only part of the control needs to be refreshed, it represents only the region that needs to be redrawn. An example of such a case would be when a control is partially obscured by another control in the user interface, and that other control is moved away, the newly exposed portion of the underneath control must be redrawn.
The code in the OnPaint method of a control runs when the control is first drawn and whenever it's invalidated. To ensure that your control is redrawn every time it's resized, add the following line to the constructor of your control:
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.ResizeRedraw, True)
Example
The following code snippet is a custom control that renders multiple colored rectangles around the edge of the control.
protected override void OnPaint(PaintEventArgs pe)
{
Rectangle rect = this.ClientRectangle;
// Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
// Otherwise, it kind of overlaps the outside edge.
rect.Width -= 1;
rect.Height -= 1;
Pen[] colorPens = new Pen[] { Pens.Blue, Pens.BlueViolet,
Pens.AliceBlue, Pens.CornflowerBlue,
Pens.Cyan, Pens.DarkCyan };
foreach (Pen pen in colorPens)
{
pe.Graphics.DrawRectangle(pen, rect);
rect.Inflate(-1, -1);
}
// Raise the Paint event so users can custom paint if they want.
base.OnPaint(pe);
}
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim rect As Rectangle = Me.ClientRectangle
'Bring the width/height in by 1 pixel so the rectangle is drawn inside the control.
'Otherwise, it kind of overlaps the outside edge.
rect.Width -= 1
rect.Height -= 1
Dim colorPens As Pen() = {Pens.Blue, Pens.BlueViolet,
Pens.AliceBlue, Pens.CornflowerBlue,
Pens.Cyan, Pens.DarkCyan}
For Each curPen As Pen In colorPens
e.Graphics.DrawRectangle(curPen, rect)
rect.Inflate(-1, -1)
Next
'Raise the Paint event so users can custom paint if they want.
MyBase.OnPaint(e)
End Sub
The previous code creates a control that looks like the following image:
Background
Notice that the background of the control is painted with the SystemColors.Control color, even though the OnPaint
code doesn't clear or fill the control with a color. The background is actually painted by the OnPaintBackground(PaintEventArgs) method before OnPaint
is called. Override OnPaintBackground
to handle drawing the background of your control. The default implementation of this method is to draw the color and image set by the BackColor and BackgroundImage properties, respectively.
Related content
.NET Desktop feedback