Wednesday, March 4, 2020
Programming a Class to Create a Custom VB.NET Control
Programming a Class to Create a Custom VB.NET 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. Heres how! 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 dont 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.IContainerNOTE: The following procedure is requiredby the Windows Form DesignerIt 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.SuspendLayout() CheckBox1 Me.CheckBox1.AutoSize True 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 isnt part of your project because its installed in Windows for all .NET programs. But theres a lot of it. Another point to be aware of is that if youre 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. Were 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 demonstrate VB.NETs inheritance. Lets 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 Color.Red Protected Overrides Sub OnPaint( ByVal pEvent _ As PaintEventArgs) Dim CenterSquare _ As New Rectangle(3, 4, 10, 12) MyBase.OnPaint(pEvent) If Me.Checked Then pEvent.Graphics.FillRectangle( New SolidBrush( CenterSquareColor ), CenterSquare) End If End SubEnd 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. 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 dont leave out of Override procedures: MyBase.OnPaint(pEvent) 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 hadnt been overridden, MyBase.OnPaint. Using the New Control 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 oldCheckBox.Height .Size New Size( oldCheckBox.Size.Width 50, oldCheckBox.Size.Height) End With Controls.Add(customCheckBox)End Sub To place the new checkbox on the form, weve 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 isnt 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. Heres 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 Color.Blue Private CenterSquareImage As Bitmap Private CenterSquare As New Rectangle( 3, 4, 10, 12) Protected Overrides Sub OnPaint _ (ByVal pEvent As _ System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(pEvent) If Me.Checked Then If CenterSquareImage Is Nothing Then pEvent.Graphics.FillRectangle( New SolidBrush( CenterSquareColor), CenterSquare) Else pEvent.Graphics.DrawImage( CenterSquareImage, CenterSquare) End If End If End Sub Public Property FillColor() As Color Get FillColor CenterSquareColor End Get Set(ByVal Value As Color) CenterSquareColor Value End Set End Property Public Property FillImage() As Bitmap Get FillImage CenterSquareImage End Get Set(ByVal Value As Bitmap) CenterSquareImage Value End Set End PropertyEnd Class Why The BetterCheckBox Version Is Better One of the main improvements is the addition of two Properties. This is something the old class didnt do at all. The two new properties introduced are FillColor and FillImage 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 Get 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 arent always required starting with VB.NET 2010, so you have to at least tell Intellisense this much to start it.) Public Property Whatever Get End Get Set(ByVal value) End SetEnd 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!, _ System.Drawing.FontStyle.Bold) Me.Size New System.Drawing.Size(200, 35) CenterSquare.Offset( 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: MyBetterEmphasizedBox.Emphasize() And just like Properties, Visual Studio automatically adds the new method to Microsofts 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 doesnt 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.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.