An Introduction to Programming a VB.NET Control With Inheritance

Create A Custom CheckBox Control!

Building complete custom components can be a very advanced project. But you can build a VB.NET class that has many of the advantages of a toolbox component with much less effort. This article shows you how, but in addition, it's a great "getting started" project that will teach you a lot about how classes and inheritance in VB.NET.

To get a flavor of what you need to do to create a complete custom component, try this experiment:

-> Open a new Windows Application project in VB.NET.
-> Add a CheckBox from the Toolbox to the form.
-> Click the "Show All Files" button at the top of Solution Explorer.

This will display the files that Visual Studio creates for your project (so you don't have to). As a historical footnote, The VB6 compiler did a lot of the same things, but you never could access the code because it was buried in compiled "p-code". You could develop custom controls in VB6 too, but it was a lot more difficult and required a special utility that Microsoft supplied just for that purpose.

In the Form Designer.vb file, you will find that the code below has been added automatically in the right locations to support the CheckBox component. (If you have a different version of Visual Studio, your code might be slightly different.) This is the code that Visual Studio writes for you.

'Required by the Windows Form Designer
Private components _
As System.ComponentModel.IContainer
'NOTE: The following procedure is required
'by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.CheckBox1 =
New System.Windows.Forms.CheckBox()
Me.CheckBox1.AutoSize =
Me.CheckBox1.Location =
New System.Drawing.Point(29, 28)
Me.CheckBox1.Name = "CheckBox1"
. . . and so forth ...

This is the code that you have to add to your program to create a custom control. Keep in mind that all the methods and properties of the actual CheckBox control are in a class supplied by the .NET Framework: System.Windows.Forms.CheckBox. This isn't part of your project because it's installed in Windows for all .NET programs. But there's a lot of it.

Another point to be aware of is that if you're using WPF (Windows Presentation Foundation), the .NET CheckBox class comes from a completely different library named System.Windows.Controls. This article only works for a Windows Forms application, but the principals of inheritance here work for any VB.NET project.

Suppose your project needs a control that is very much like one of the standard controls. For example, a checkbox that changed color, or displayed a tiny "happy face" instead of displaying the little "check" graphic. We're going to build a class that does this and show you how to add it to your project. While this might be useful by itself, the real goal is to deomontrate VB.NET's inheritance.

Let's Start Coding!

To get started, change the name of the CheckBox that you just added to oldCheckBox. (You might want to stop displaying "Show All Files" again to simplify Solution Explorer.) Now add a new class to your project. There are several ways to do this including right-clicking the project in Solution Explorer and selecting "Add" then "Class" or selecting "Add Class" under under the Project menu item. Change the file name of the new class to newCheckBox to keep things straight. Finally, open the code window for the class and add this code:

Public Class newCheckBox
Inherits CheckBox
Private CenterSquareColor As Color =
Protected Overrides Sub OnPaint(
ByVal pEvent _
As PaintEventArgs)
Dim CenterSquare _
As New Rectangle(3, 4, 10, 12)
If Me.Checked Then
New SolidBrush(
End If
End Sub
End Class

(In this article and in others on the site, a lot of line continuations are used to keep lines short so they will fit into the space available on the web page.)

The first thing to notice about your new class code is the Inherits keyword. That means that all the properties and methods of a VB.NET Framework CheckBox are automatically part of this one. To appreciate how much work this saves, you have to have tried programming something like a CheckBox component from scratch.

There are two key things to notice in the code above:

The first is the code uses Override to replace the standard .NET behavior that would take place for an OnPaint event. An OnPaint event is triggered whenever Windows notices that part of your display has to be reconstructed. An example would be when another window uncovers part of your display. Windows updates the display automatically, but then calls the OnPaint event in your code. (The OnPaint event is also called when the form is initially created.) So if we Override OnPaint, we can change the way things look on the screen.

The second is the way Visual Basic creates the CheckBox. Whenever the parent is "Checked" (that is, Me.Checked is True) then the new code we provide in our NewCheckBox class will recolor the center of the CheckBox instead of drawing a checkmark.

The rest is what is called GDI+ code. This code selects a rectangle the exact same size as the center of a Check Box and colors it in with GDI+ method calls. (GDI+ is covered in a different tutorial: GDI+ Graphics in Visual Basic .NET. The "magic numbers" to position the red rectangle, "Rectangle(3, 4, 10, 12)", were determined experimentally. I just changed it until it looked right.

There is one very important step that you want to make sure you don't leave out of Override procedures:


Override means that your code will provide all of the code for the event. But this is seldom what you want. So VB provides a way to run the normal .NET code that would have been executed for an event. This is the statement that does that. It passes the very same parameter - pEvent - to the event code that would have been executed if it hadn't been overridden - MyBase.OnPaint.

On the next page, we put the new control to use!

On the previous page, this article showed how to create a custom control using VB.NET and inheritance. Using the control is explained now.

Because our new control is not in our toolbox, it has to be created in the form with code. The best place to do that is in the form Load event procedure.

Open the code window for the form load event procedure and add this code:

Private Sub frmCustCtrlEx_Load(
ByVal sender As System.Object,
ByVal e As System.EventArgs
) Handles MyBase.Load
Dim customCheckBox As New newCheckBox()
With customCheckBox
.Text = "Custom CheckBox"
.Left = oldCheckBox.Left
.Top = oldCheckBox.Top +
.Size = New Size(
oldCheckBox.Size.Width + 50,
End With
End Sub

To place the new checkbox on the form, we've taken advantage of the fact that there is already one there and just used the size and position of that one (adjusted so the Text property will fit). Otherwise we would have to code the position manually. When MyCheckBox has been added to the form, we then add it to the Controls collection.

But this code isn't very flexible. For example, the color Red is hardcoded and changing the color requires changing the program. You might also want a graphic instead of a check mark.

Here's a new, improved CheckBox class. This code shows you how to take some of the next steps toward VB.NET object oriented programming.

Public Class betterCheckBox
Inherits CheckBox
Private CenterSquareColor As Color =
Private CenterSquareImage As Bitmap
Private CenterSquare As New Rectangle(
3, 4, 10, 12)
Protected Overrides Sub OnPaint _
(ByVal pEvent As _
If Me.Checked Then
If CenterSquareImage Is Nothing Then
New SolidBrush(
End If
End If
End Sub
Public Property FillColor() As Color
FillColor = CenterSquareColor
End Get
Set(ByVal Value As Color)
CenterSquareColor = Value
End Set
End Property
Public Property FillImage() As Bitmap
FillImage = CenterSquareImage
End Get
Set(ByVal Value As Bitmap)
CenterSquareImage = Value
End Set
End Property
End Class

On the next page, some of the features of the new, improved code are explained.

The previous pages of this article contained the code for two versions of an inherited Visual Basic control. This page tells you why the BetterCheckBox version is better.

One of the main improvements is the addition of two Properties. This is something the old class didn't do at all.

The two new properties introduced are




To get a flavor of how this works in VB.NET, try this simple experiment. Add a class to a standard project and then enter the code:

Public Property Whatever

When you press Enter after typing "Get", VB.NET Intellisense fills in the entire Property code block and all you have to do is code the specifics for your project. (The Get and Set blocks aren't always required starting with VB.NET 2010, so you have to at least tell Intellisense this much to start it.)

Public Property Whatever
End Get
Set(ByVal value)
End Set
End Property

These blocks have been completed in the code above. The purpose of these blocks of code is to allow property values to be accessed from other parts of the system.

With the addition of Methods, you would be well on the way to creating a complete component. To see a very simple example of a Method, add this code below the Property declarations in the betterCheckBox class:

Public Sub Emphasize()
Me.Font = New System.Drawing.Font( _
"Microsoft Sans Serif", 12.0!, _
Me.Size =
New System.Drawing.Size(200, 35)
CenterSquare.Left - 3,
CenterSquare.Top + 3)
End Sub

In addition to adjusting the Font displayed in a CheckBox, this method also adjusts the size of the box and the location of the checked rectangle to account for the new size. To use the new method, just code it the same way you would any method:


And just like Properties, Visual Studio automatically adds the new method to Microsoft's Intellisense!

The main goal here is to simply demonstrate how a method is coded. You may be aware that a standard CheckBox control also allows the Font to be changed, so this method doesn't really add much function. The next article in this series, Programming a Custom VB.NET Control - Beyond the Basics!, shows a method that does, and also explains how to override a method in a custom control.