In the previous sections, you learned how to combine Windows controls, components, and code into reusable composite controls. Your composite control can now be used as a base upon which other controls can be built. The process of deriving a class from a base class is called inheritance. In this section, you will create a composite control called ctlAlarmClock. This control will be derived from its parent control, ctlClock. You will learn to extend the functionality of ctlClock by overriding parent methods and adding new methods and properties.
The first step in creating an inherited control is to derive it from its parent. This action creates a new control that has all of the properties, methods, and graphical characteristics of the parent control, but can also act as a base for the addition of new or modified functionality.
To create the inherited control
In Solution Explorer, right-click ctlClockLib, point to Add, and then click User Control.
The Add New Item dialog box opens.
Select the Inherited User Control template.
In the Name box, type ctlAlarmClock.vb, and then click Add.
The Inheritance Picker dialog box appears.
Under Component Name, double-click ctlClock.
In Solution Explorer, browse through the current projects.
Note: |
|---|
A file called ctlAlarmClock.vb has been added to the current project. |
Adding the Alarm Properties
Properties are added to an inherited control in the same way they are added to a composite control. You will now use the property declaration syntax to add two properties to your control: AlarmTime, which will store the value of the date and time the alarm is to go off, and AlarmSet, which will indicate whether the alarm is set.
To add properties to your composite control
In Solution Explorer, right-click ctlAlarmClock, and then click View Code.
Locate the class declaration for the ctlAlarmClock control, which appears as Public Class ctlAlarmClock. In the class declaration, insert the following code.
[Visual Basic]
Private dteAlarmTime As Date
Private blnAlarmSet As Boolean
' These properties will be declared as Public to allow future
' developers to access them.
Public Property AlarmTime() As Date
Get
Return dteAlarmTime
End Get
Set(ByVal value as Date)
dteAlarmTime = value
End Set
End Property
Public Property AlarmSet() As Boolean
Get
Return blnAlarmSet
End Get
Set(ByVal value as Boolean)
blnAlarmSet = value
End Set
End Property
Adding to the Graphical Interface of the Control
Your inherited control has a visual interface that is identical to the control it inherits from. It possesses the same constituent controls as its parent control, but the properties of the constituent controls will not be available unless they were specifically exposed. You may add to the graphical interface of an inherited composite control in the same manner as you would add to any composite control. To continue adding to your alarm clock's visual interface, you will add a label control that will flash when the alarm is sounding.
To add the label control
In Solution Explorer, right-click ctlAlarmClock, and click View Designer.
The designer for ctlAlarmClock opens in the main window.
Click lblDisplay (the display portion of the control), and view the Properties window.
Note: |
|---|
While all the properties are displayed, they are dimmed. This indicates that these properties are native to lblDisplay and cannot be modified or accessed in the Properties window. By default, controls contained in a composite control are Private, and their properties are not accessible by any means. |
Note: |
|---|
If you want subsequent users of your composite control to have access to its internal controls, declare them as Public or Protected. This will allow you to set and modify properties of controls contained within your composite control by using the appropriate code. |
Add a Label control to your composite control.
Using the mouse, drag the Label control immediately beneath the display box. In the Properties window, set the following properties.
Property | Setting |
|---|
Name | lblAlarm |
Text | Alarm! |
TextAlign | MiddleCenter |
Visible | False |
Adding the Alarm Functionality
In the previous procedures, you added properties and a control that will enable alarm functionality in your composite control. In this procedure, you will add code to compare the current time to the alarm time and, if they are the same, to sound and flash an alarm. By overriding the Timer1_Tick method of ctlClock and adding additional code to it, you will extend the capability of ctlAlarmClock while retaining all of the inherent functionality of ctlClock.
To override the Timer1_Tick method of ctlClock
In Solution Explorer, right-click ctlAlarmClock.vb, and then click View Code.
Locate the Private blnAlarmSet As Boolean statement. Immediately beneath it, add the following statement.
[Visual Basic]
Dim blnColorTicker as Boolean
Locate the End Class statement at the bottom of the page. Just before the End Class statement, add the following code.
[Visual Basic]
Protected Overrides Sub Timer1_Tick(ByVal sender As Object, ByVal e _
As System.EventArgs)
' Calls the Timer1_Tick method of ctlClock.
MyBase.Timer1_Tick(sender, e)
' Checks to see if the Alarm is set.
If AlarmSet = False Then
Exit Sub
End If
' If the date, hour, and minute of the alarm time are the same as
' now, flash and beep an alarm.
If AlarmTime.Date = Now.Date And AlarmTime.Hour = Now.Hour And _
AlarmTime.Minute = Now.Minute Then
' Sounds an audible beep.
Beep()
' Sets lblAlarmVisible to True, and changes the background color based on the
' value of blnColorTicker. The background color of the label will
' flash once per tick of the clock.
lblAlarm.Visible = True
If blnColorTicker = False Then
lblAlarm.BackColor = Color.PeachPuff
blnColorTicker = True
Else
lblAlarm.BackColor = Color.Plum
blnColorTicker = False
End If
Else
' Once the alarm has sounded for a minute, the label is made
' invisible again.
lblAlarm.Visible = False
End If
End Sub
The addition of this code accomplishes several tasks. The Overrides statement directs the control to use this method in place of the method that was inherited from the base control. When this method is called, it calls the method it overrides by invoking the MyBase.Timer1_Tick statement, ensuring that all of the functionality incorporated in the original control is reproduced in this control. It then runs additional code to incorporate the alarm functionality. A flashing label control will appear when the alarm occurs, and an audible beep will be heard.
Note: |
|---|
Because you are overriding an inherited event handler, you do not have to specify the event with the Handles keyword. The event is already hooked up. All you are overriding is the implementation of the handler. |
Your alarm clock control is almost complete. The only thing that remains is to implement a way to turn it off. To do this, you will add code to the lblAlarm_Click method.
To implement the shutoff method
In Solution Explorer, right-click ctlAlarmClock.vb, and then click View Designer.
In the designer, double-click lblAlarm. The Code Editor opens to the Private Sub lblAlarm_Click line.
Modify this method so that it resembles the following code.
[Visual Basic]
Private Sub lblAlarm_Click(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles lblAlarm.Click
' Turns off the alarm.
AlarmSet = False
' Hides the flashing label.
lblAlarm.Visible = False
End Sub
On the File menu, click Save All to save the project.
Using the Inherited Control on a Form
You can test your inherited control the same way you tested the base class control, ctlClock: Press F5 to build the project and run your control in the UserControl Test Container. For more information, see How to: Test the Run-Time Behavior of a UserControl.
To put your control to use, you will need to host it on a form. As with a standard composite control, an inherited composite control cannot stand alone and must be hosted in a form or other container. Since ctlAlarmClock has a greater depth of functionality, additional code is required to test it. In this procedure, you will write a simple program to test the functionality of ctlAlarmClock. You will write code to set and display the AlarmTime property of ctlAlarmClock, and will test its inherent functions.
To build and add your control to a test form
In Solution Explorer, right-click ctlClockLib, and then click Build.
On the File menu, point to Add, and then click New Project.
Add a new Windows Application project to the solution, and name it Test.
The Test project is added to Solution Explorer.
In Solution Explorer, right-click the Test project node, and then click Add Reference to display the Add Reference dialog box.
Click the tab labeled Projects. The project ctlClockLib will be listed under Project Name. Double-click ctlClockLib to add the reference to the test project.
In Solution Explorer, right-click Test, and then click Build.
In the Toolbox, expand the ctlClockLib Components node.
Double-click ctlAlarmClock to add an instance of ctlAlarmClock to your form.
In the Toolbox, locate and double-click DateTimePicker to add a DateTimePicker control to your form, and then add a Label control by double-clicking Label.
Use the mouse to position the controls in a convenient place on the form.
Set the properties of these controls in the following manner.
Control | Property | Value |
|---|
label1 | Text | (blank space) |
| Name | lblTest |
dateTimePicker1 | Name | dtpTest |
| Format | Time |
In the designer, double-click dtpTest.
The Code Editor opens to Private Sub dtpTest_ValueChanged.
Modify the code so that it resembles the following.
[Visual Basic]
Private Sub dtpTest_ValueChanged(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles dtpTest.ValueChanged
ctlAlarmClock1.AlarmTime = dtpTest.Value
ctlAlarmClock1.AlarmSet = True
lblTest.Text = "Alarm Time is " & Format(ctlAlarmClock1.AlarmTime, _
"hh:mm")
End Sub
In Solution Explorer, right-click Test, and then click Set as StartUp Project.
On the Debug menu, click Start Debugging.
The test program starts. Note that the current time is updated in the ctlAlarmClock control, and that the starting time is shown in the DateTimePicker control.
Click the DateTimePicker where the minutes of the hour are displayed.
Using the keyboard, set a value for minutes that is one minute greater than the current time shown by ctlAlarmClock.
The time for the alarm setting is shown in lblTest. Wait for the displayed time to reach the alarm setting time. When the displayed time reaches the time to which the alarm is set, the beep will sound and lblAlarm will flash.
Turn off the alarm by clicking lblAlarm. You may now reset the alarm.
This walkthrough has covered a number of key concepts. You have learned to create a composite control by combining controls and components into a composite control container. You have learned to add properties to your control, and to write code to implement custom functionality. In the last section, you learned to extend the functionality of a given composite control through inheritance, and to alter the functionality of host methods by overriding those methods.