Visual Basic Concepts

Saving the ShapeLabel Control's Property Values

You can add properties and methods to an ActiveX control in the same way you add them to class modules: by creating Public procedures. Since ShapeLabel is going to be an enhanced label control, it makes sense for it to have a Caption property.

The following procedure adds a Caption property, and the support code to save and retrieve the property value. A control’s property values are saved along with the other data that describes the container — in this case, Form1.

Note   This topic is part of a series that walks you through creating a sample ActiveX control. IIt begins with the topic Creating an ActiveX Control.

To add a Caption property to the ShapeLabel control

  1. In the Project Explorer window, double-click ShapeLabel to open its designer, then double-click on ShapeLabel to bring its code window to the front.

  2. On the Tools menu, click Add Procedure to open the Add Procedure dialog box. In the Name box, enter the name Caption. Click Property and Public, then click OK.

  3. In the Code window, change the newly created property procedures to appear as follows:

    Public Property Get Caption() As String
       Caption = lblCaption.Caption
    End Property
    
    Public Property Let Caption( _
             ByVal NewCaption As String)
       lblCaption.Caption = NewCaption
       PropertyChanged "Caption"
    End Property
    

    Note   Be careful to change both property declaration lines by adding As String, as shown above. Property Get and Property Let declarations must match. Using specific type names speeds up execution, and provides type checking for the developer who uses your control.

    The Property Let procedure is executed whenever a new value is assigned to the Caption property. It stores the new value directly in the Caption property of the lblCaption label on ShapeLabel.

    The Property Get procedure is executed whenever the property value is retrieved. It reads the value stored in the Caption property of the lblCaption label.

    Property Let procedures in controls must call PropertyChanged, as explained in "Adding Properties to Controls" in "Building ActiveX Controls." This tells the Properties window to refresh its display, and informs Visual Basic that the form has changed.

    Property procedures are discussed in "Adding Properties to a Class," in "Programming with Objects" in the Visual Basic Programmer’s Guide.

  4. To initialize the Caption property, add the following code to the UserControl_InitProperties event procedure:

    Private Sub UserControl_InitProperties()
       ' Let the starting value for the Caption
       '   property be the Name given to this
       '   instance of ShapeLabel.
       Caption = Extender.Name
       Debug.Print "InitProperties"
    End Sub
    

    What is this Extender object? To the user of a control, extender properties — such as Name, Top, and Left — appear to be part of your control. However, extender properties are really provided by the container your control is placed on. The Extender object of the UserControl gives you, the control designer, access to these properties from within your control.

    The read-only Name property of the Extender object returns the name the container (or the user) gives to a specific instance of your control. Using this name (for example, ShapeLabel1) as the initial value of the Caption property mimics the behavior of the Label control.

Tip   If your control imitates the behavior of controls that provide similar functionality, using it will be more intuitive.

What would happen if you created a Name property for your control? You would be able to access it from within your control, but the only Name property your user would see would be the Name property of the Extender object.

This introduces a recurrent theme for controls: The container determines a large portion of your control’s behavior and appearance. It’s the container that determines your control’s Name, and your Top and Left properties are maintained relative to the container’s coordinates. This theme will be taken up again in "Building ActiveX Controls."

One last item of business: Why put this code in the InitProperties event? Why not use the Initialize event? As you have seen, Initialize is called every time the control instance is created, which happens often. InitProperties happens only when the user places the control on the container. This makes it the appropriate place to set initial values for a control instance.

In addition, the UserControl object’s Extender and AmbientProperties objects are not yet available when the Initialize event occurs. "Understanding Control Lifetime and Key Events," in "Building ActiveX Controls," discusses appropriate uses of the Initialize event.

  1. To save the value of your Caption property, add the following code to the UserControl_WriteProperties event procedure:

    Private Sub UserControl_WriteProperties(PropBag As _
          PropertyBag)
       Debug.Print "WriteProperties"
       PropBag.WriteProperty "Caption", Caption, _
          Extender.Name
    End Sub
    

    The PropertyBag is just what its name implies, a "bag" in which property values are saved. The bag is provided by the container. You can’t see into it, and you have no idea where or how the data is saved. All you can do is put values in and take them out.

    The first argument of the WriteProperty method is the name of the property, which will be used as the retrieval key. You should use the name of the property for this argument, because it will appear in the .frm text file (in Visual Basic—other containers may use other file names to save project data), and may be seen by the user of the control.

    The second argument is the value. A property value is saved as a Variant.

    The third argument, oddly enough, is a default value. Why provide a default when saving the property value? Before saving the value, the WriteProperty method compares the property value with this default. If they are the same, the property value doesn’t have to be saved, because default values will be set automatically when the control is reloaded. This keeps the .frm file from being cluttered with hundreds of default entries, a great favor to your users!

  2. Place the following code in the ReadProperties event, to retrieve the persisted property value for the Caption property:

    Private Sub UserControl_ReadProperties(PropBag As _
          PropertyBag)
       Debug.Print "ReadProperties"
       Caption = PropBag.ReadProperty("Caption", _
          Extender.Name)
    End Sub
    

    The second argument of the ReadProperty method is a default value to be used if no value has been saved, if the user has deleted the property from the text file, or if the value has never been changed from the default, and therefore never saved by WriteProperty.

  3. Be sure the ShapeLabel designer is in front, then click the Close button or press CTRL+F4 to close the window, putting the control into run mode. Like magic, the captions of the ShapeLabel controls change to match the default names of the two instances, ShapeLabel1 and ShapeLabel2.

    Use the Properties window to change the Caption properties of the two ShapeLabel controls on Form1, then click the Close button on the Form1 designer. In the Project Explorer window, double-click Form1 to re-open the Form1 designer.

    From the messages in the Immediate window, you can see that the controls have been destroyed and re-created, but the values of the Caption properties have been saved and retrieved.

  4. Press CTRL+F5 to run TestCtlDemo, the Startup project of the project group, and observe the run-time behavior of the ShapeLabel control.

  5. Click the Close button on Form1 to return to design mode.

For More Information   Details of saving and retrieving property values can be found in "Adding Properties to Controls," 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.

To See
Go to the next step Giving the ShapeLabel Control a Property Page
Start from the beginning Creating an ActiveX Control