Creating Custom Controls


Visual Basic .NET Unleashed
By Paul Kimmel
Table of Contents
Chapter 16.  Designing User Interfaces

Creating Custom Controls

What is the difference between a UserControl and a custom control? Not much. The UserControl jumpstarts creating custom controls because it provides you with a form-like canvas to paint controls on. However, if you want to extend the behavior of an existing control, rather than starting from scratch, you want to implement a custom control.

The most significant difference is that when you define a custom control, you will modify the Inherits statement to inherit from a specific existing control. When you inherit from an existing control, you get all of the behaviors and attributes of that existing control and anything else you add. The section "Creating a Custom Component" in Chapter 12, "Defining Attributes," demonstrates creating a custom label.

In other respects, creating a custom component is identical to creating a UserControl, except for having the UserControl designer to draw components on.

Several additional factors apply to controls in general. You do not need to implement a class library or Windows control library to create a custom control. You can create the control in a Windows application; this is a reasonable approach if the control will only be used in that application. You can also start a custom control as a UserControl and change your mind, making the same control a custom control by changing the Inherits statement. To effect the conversion, simply modify the Inherits System.Windows.Forms.UserControl to inherit from some other specific control, for example, Inherits System.Windows.Forms.Button.

The class library and Windows control library projects are there to help you get started but are not required aspects of creating controls. Keep in mind that controls are classes, and you can introduce them anywhere and at any time in your application where it makes sense to do so.

Creating a Nonvisual Component

There are several instances of user and custom controls throughout this book that demonstrate the mechanics of creating components. For this reason I have added an example of a nonvisual component in this section.

A nonvisual component is a component that generalizes the Component class. An example is the familiar Timer component. The component in Listing 16.10 wraps the events of the Application object, representing a Windows Forms application. By wrapping the events in the ApplicationEvents class, it becomes much easier to associate event handlers with Application events.

Listing 16.10 Wrapping the application object events in a component
  1:  Imports System.Threading  2:  Imports System.Windows.Forms  3:  Imports System.ComponentModel  4:   5:   6:  Public Class ApplicationEvents  7:  Inherits System.ComponentModel.Component  8:   9:  Public Event ApplicationExit As EventHandler  10:  Public Event Idle As EventHandler  11:  Public Event ThreadException As ThreadExceptionEventHandler  12:  Public Event ThreadExit As EventHandler  13:   14:  Public Sub New()  15:  AddHandler Application.ApplicationExit, _  16:  AddressOf DoApplicationExit  17:  AddHandler Application.Idle, _  18:  AddressOf DoIdle  19:   20:  AddHandler Application.ThreadException, _  21:  AddressOf DoThreadException  22:  AddHandler Application.ThreadExit, _  23:  AddressOf DoThreadExit  24:  End Sub  25:   26:  Private Sub DoApplicationExit(ByVal sender As Object, _  27:  ByVal e As System.EventArgs)  28:  RaiseEvent ApplicationExit(sender, e)  29:  End Sub  30:   31:  Private Sub DoIdle(ByVal sender As Object, _  32:  ByVal e As System.EventArgs)  33:   34:  RaiseEvent Idle(sender, e)  35:  End Sub  36:   37:  Private Sub DoThreadException(ByVal sender As Object, _  38:  ByVal e As ThreadExceptionEventArgs)  39:   40:  RaiseEvent ThreadException(sender, e)  41:   42:  End Sub  43:   44:  Public Sub DoThreadExit(ByVal sender As Object, _  45:  ByVal e As System.EventArgs)  46:   47:  RaiseEvent ThreadExit(sender, e)  48:   49:  End Sub  50:  End Class 

The ApplicationEvents component in Listing 16.10 inherits from Component. When you add it to a form, it will actually be added to the component tray. There are four events on lines 9 through 12 that exactly mirror the four Application events. The constructor on lines 14 to 24 adds the ApplicationEvents handlers to the Application events. When Application raises any of these events, the ApplicationEvents component receives the event and re-raises it, passing the event notification to the respondent.

We add a very modest procedural indirection by layering in a component, but we obtain maximum ease of use.

Test the ApplicationEvents component by installing the component and adding code to handle the individual events.

Specifying the Default Event

When you click on a form or a button, have you gotten around to wondering how a default event handler is selected and generated? Wonder no more. The System. ComponentModel.DefaultEventAttribute accepts the name of the event that is designated as the default event. If you add the following statement on line 5 of Listing 16.10, it will designate the Idle event as the default event for the ApplicationEvents class.

 <DefaultEvent("Idle")> _ 

Recompile ApplicationEvents.vbproj. Now when you click the ApplicationEvents component, an Idle event handler will be generated by default. Of course, you can still pick individual events in the code designer, and the method bodies for those will be generated, too.


Visual BasicR. NET Unleashed
Visual BasicR. NET Unleashed
Year: 2001
Pages: 222 © 2008-2017.
If you may any questions please contact us: