Visual Basic Concepts
Life and Times of a UserControl Object
The life of an ordinary Visual Basic form is marked by certain key events, such as Initialize, Load, QueryUnload, and Unload. In order to create well-behaved applications, it’s important to know when these events occur in the life cycle of a form.
The same is true for controls. The key events in the life cycle of a UserControl are Initialize, InitProperties, ReadProperties, WriteProperties, and Terminate. The following procedure explores these events.
*Note* This topic is part of a series that walks you through creating a sample ActiveX control. It begins with the topic Creating an ActiveX Control.
To observe key events for ShapeLabel
In the Project Explorer window, double-click ShapeLabel to open its designer.
Double-click the designer to open a code window for ShapeLabel, and enter code in the following event procedures:
Private Sub UserControl_Initialize() Debug.Print "Initialize" End Sub Private Sub UserControl_InitProperties() Debug.Print "InitProperties" End Sub Private Sub UserControl_ReadProperties(PropBag As _ PropertyBag) Debug.Print "ReadProperties" End Sub Private Sub UserControl_WriteProperties(PropBag _ As PropertyBag) Debug.Print "WriteProperties" End Sub Private Sub UserControl_Terminate() Debug.Print "Terminate" End Sub
*Note* For UserControl objects, Load and Unload are superseded by the ReadProperties and WriteProperties events. This is discussed in more detail in "Understanding Control Lifetime and Key Events," in "Building ActiveX Controls."
Be sure the ShapeLabel designer is in front, then press CTRL+F4 to close the window, putting the control in run mode. Debug messages will appear in the Immediate window:
What’s going on here? You haven’t put another instance of the ShapeLabel control on Form1. Where did all these events come from?
This illustrates an important point about controls. A user puts a control on a form, and thereafter thinks of the control as a permanent fixture of the form. From the control author’s perspective, however, controls are getting destroyed and re-created all the time.
When you put ShapeLabel in run mode by closing its designer, the instance of ShapeLabel on Form1 was destroyed and re-created, at which point it received an Initialize event. Why didn’t you see a Terminate event first? Because the original instance of ShapeLabel you placed on Form1 was created before you added the code in the UserControl_Terminate event procedure! Welcome to the wild and woolly world of control creation.
*Note* Control instances are also destroyed and recreated when you click Update UserControls on the form’s context menu.
Press CTRL+F5, or click the Start button on the toolbar, to run TestCtlDemo. When the project is running, the grid on Form1 is gone, so you can’t see the ShapeLabel, but you can see its life flash before your eyes in the Immediate window:
After a control instance is created, the ReadProperties event gives you a chance to obtain the control’s saved property values from the .frm file belonging to the form that contains the control instance.
When the design-time instance of the control is destroyed, the WriteProperties event gives you a chance to save the property values set at design time by the developer who's using your control. Property values are saved in the containing form’s .frm file, as you’ll see in "Saving the ShapeLabel Control's Property Values," later in this chapter.
The Terminate event occurs when the control is being destroyed.
*Note* By default, the Compile On Demand option is checked on the General tab of the Options dialog box (accessed from the Tools menu). Using CTRL+F5 (or Start with Full Compile, on the Run menu) overrides Compile On Demand, and fully compiles all the projects in the group before entering run mode. This is useful because compile errors usually require resetting the project, which means returning to design mode. When you’re debugging controls, you may prefer to turn Compile On Demand off rather than remembering to use CTRL+F5.
Close Form1, to return the project to design mode. In the Immediate window, you’ll see a Terminate event (but not WriteProperties — why not?) as the run-time instance of ShapeLabel is torn down. Then you’ll see the Initialize, ReadProperties, and Resize events, as the design-time instance of the control is created.
The run-time instance of a control never gets a WriteProperties event, because it doesn’t need to save its property values. To see why not, consider ShapeLabel’s future. When it’s compiled into an .ocx file, you’ll add it to another project, put an instance on a form, compile the project into an .exe, and run it. When you close that .exe, the only place the ShapeLabel instance could save its property values would be in the .exe file. This sort of behavior is not tolerated by well-behaved operating systems.
Scroll to the top of the Immediate window, click in the top left corner, and drag to select all the text in the window. Press the DELETE key to clear the window.
In the Project Explorer window, double-click Form1 to bring Form1 to the front.
On the Toolbox, double-click the ShapeLabel icon to add another instance of the control to Form1. You’ll see a new event this time.
When a new instance of your control is placed on a container, it gets an InitProperties event. In the UserControl_InitProperties event procedure you can place code to:
Set the default values for each of the control’s properties values
Perform tasks whenever a user creates an instance of your control.
Close the Form1 designer by clicking its Close button or pressing CTRL+F4 while the designer is in front. In the Immediate window, you will see two sets of WriteProperties and Terminate events, one for each instance of ShapeLabel.
In the Project Explorer window, double-click Form1 to open its designer again. When the designer opens, all the controls on Form1 are created, and their Initialize events are fired. All controls then receive ReadProperties events, which allow them to retrieve their saved property values. The InitProperties event does not occur, because both instances of the ShapeLabel control already exist.
*For More Information* Control lifetime, and key events therein, are discussed in "Understanding Control Lifetime and Key Events," in Chapter 9, "Building ActiveX Controls." "Exposing Properties of Constituent Controls," in the same chapter, explains how the ActiveX Control Interface Wizard simplifies the creation of code to save and retrieve property values.Control lifetime, and key events therein, are discussed in "Understanding Control Lifetime and Key Events," in "Building ActiveX Controls." "Exposing Properties of Constituent Controls," in the same chapter, explains how the ActiveX Control Interface Wizard simplifies the creation of code to save and retrieve property values.
Step by Step
This topic is part of a series that walks you through creating a sample ActiveX control.
|Go to the next step||Drawing the ShapeLabel Control|
|Start from the beginning||Creating an ActiveX Control|