|
As previously mentioned, you need to draw your own user interface when you create a custom control by inheriting the Control or UserControl class. Not only are you responsible for drawing the GUI the first time the control is displayed, you must also repaint it when the control is resized, when the control is restored after being minimized, and whenever the GUI needs to repainted. The way to do this is by overriding the OnPaint method in your class:
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) ... End Sub
The OnPaint method is automatically called when the control needs to be repainted. This method receives a System.Windows.Forms.PaintEventArgs object from which you can obtain a reference to the System.Drawing.Graphics object of the control. Use this Graphics object to draw your GUI.
Listing 1-1 shows how easy it is to use the OnPaint method to draw your GUI. It shows the code for a simple custom control called RoundButton, which is a round button that has all the properties, methods, and events of the Control class. However, it has its own GUI, which is a circle with some text. Even though the class only has 14 lines, it functions as a proper control. For instance, you can capture the Click event so that you can have some code execute when a user clicks it.
Listing 1-1: A Simple Custom Control That Paints Its Own GUI
Imports System.Windows.Forms Imports System.Drawing Public Class RoundButton : Inherits UserControl Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) Dim graphics As Graphics = e.Graphics Dim pen As New Pen(Color.BlueViolet) Dim area As New Rectangle(0, 0, 90, 90) graphics.DrawEllipse(pen, area) ' draw the value of the Text property Dim font As New Font("Times New Roman", 10) Dim brush As Brush = New SolidBrush(Color.Black) graphics.DrawString(Me.Text, font, brush, 10, 35) End Sub End Class
The RoundButton class extends the UserControl class and overrides its OnPaint method. In this method, you first obtain the Graphics object from the PaintEventArgs object. You then create a System.Drawing.Pen object and a System.Drawing.Rectangle object and pass them to the DrawEllipse method of the Graphics class. The result from calling the DrawEllipse method is a circle.
The second part of the OnPaint method in Listing 1-1 uses the DrawString method of the Graphics class to print the value of the Text property of this control.
Note | To compile the code in Listing 1-1, use the following command from the directory in which the listing-01.01.vb file resides: vbc /t:library /r:System.dll,System.Windows.Forms.dll, System.Drawing.dll listing-01.01.vb /out:RoundButton.dll (all on one line). The outcome of the compilation is a DLL file named RoundButton.dll. |
After you compile the class, you can put it on a form just like you would a normal control. For example, Listing 1-2 shows a form that includes a RoundButton control.
Listing 1-2: Using the RoundButton Control
Imports System Public Class MyForm : Inherits System.Windows.Forms.Form Private myButton As New RoundButton() Public Sub New() myButton.Location = New System.Drawing.Point(24, 24) myButton.Size = New System.Drawing.Size(100, 100) myButton.Text = "Show Magic" Me.Controls.Add(myButton) Me.Text = "Demonstrating Round Button" End Sub <STAThread()> Shared Sub Main() System.Windows.Forms.Application.Run(New MyForm()) End Sub End Class
To compile this form, from the directory where the .vb file resides, type the following:
vbc /t:winexe /r:System.dll,System.Windows.Forms.dll,System.Drawing.dll, RoundButton.dll listing-01.02.vb
You can then double-click the resulting .exe file. Figure 1-1 shows the control in a form.
Figure 1-1: The RoundButton control
Although the OnPaint method is useful for painting the whole GUI, in many occasions you need to modify only some part of the GUI. Redrawing the whole lot will be a waste of resource and processor cycles if all you need, for instance, is to update a character in a document. And, repainting parts that have not changed can also cause flickers. To selectively repaint part of the Graphics object's area, you invalidate the area in the Graphics object of your control and force the control to repaint the area. For this purpose, you use the Invalidate and Update methods.
The Invalidate method invalidates a specific area of the control and causes a paint message to be sent to the control. This method has six overloads. One of these overloads accepts a Rectangle representing the area to be invalidated. Another overload accepts no argument, which will cause the whole area of the control to be invalidated.
After calling the Invalidate method, you need to call the Update method to repaint the invalidated area. The Update method will cause the OnPaint method to be called, but only the invalidated area is redrawn.
|