I'm going to start by putting my code, which is a little bit different from Foada's in a couple of places, to avoid confusion. Foada's is perfectly correct, though, except for a little bug.
Code:
'This code assumes a user control named MyControl with a single label, named Label1.
Option Explicit
Public Property Get Caption() As String
Caption = Label1.Caption
End Property
Public Property Let Caption(cVal As String)
Label1.Caption = cVal
PropertyChanged "Caption"
End Property
Private Sub UserControl_InitProperties()
Caption = Extender.Name
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
Me.Caption = PropBag.ReadProperty("Caption", Extender.Name)
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Caption", Extender.Name
End Sub
Now, the reason for all these events and things has to do with getting property values to persist between instances of your control. When you first place a control on your form, or load a saved form with the control on it, you create a design time instance of it. When you hit the run button, you destroy the design time instance and create a run time instance. When you stop your program (running from the ide, that is), you do the reverse.
The problem is how to make property values persist between these instances, and all this code is there to support that. Property values are stored in a "PropertyBag" object. This object has two methods: ReadProperty and WriteProperty. Values in the property bag can be transferred between instances of your control.
The InitProperties event fires the first time you put the label on your form, and at no other time. The ReadProperties event fires whenever you open an instance of the control, whether a design time or run time instance. So, it happens when you hit the run button or the stop button, or open a form in design time. The WriteProperties event happens when you close a design time instance of the form. Finally, the PropertyChanged statement notifies VB that the current value for the property has changed. If you don't do this, the PropertyBag.WriteProperty method won't have any effect.
In Foada's code, the LabelCaption property will be "Not Set" when you first place the control on the form, which is fine. In my code, the Caption property (same as Foada's LabelCaption property) is whatever the Form says the name of the control is, in this case MyControl1, MyControl2, etc. Both of our codes map the Label1 Caption property to the controls LabelCaption/Caption property. (Check
for more on the Extender object.)
Now, if you put my code and Foada's up, and draw one of each control on the form, and then close the form and reopen it, you'll see that Foada's label says Label1 on it. Furthermore, if you make changes to the property, and run the program, it will still say Label1. In other words, any provided property values fail to persist between instances.
In case you would like to figure out why on your own, I put the fix in a white box (highlight it to see it).
Code:
[white] Substitute LabelCaption for m_strLabelCaption in both the ReadProperties and WriteProperties event. The problem occurs because m_strLabelCaption is never actually mapped to the LabelCaption property in the persistence mechanism. ReadProperties reads the value into the variable, but this doesn't call the property let procedure. Writeproperties writes the current value of m_strLabelCaption into the property bag, but if you have changed the property, the change is stored to Label1.Caption, not mStrLabelCaption, so the changes don't persist.
Usually, property procedures store current values in a private variable. In ActiveX controls, it's more typical to store current values in a property of a constituent control, since the property procedures are functioning as a mechanism to expose constituent control properties as properties of the ActiveX control. So, you don't need a private variable. Foada probably started with a private variable, remembered that you could map the property directly to the Label1.Caption property, and forgot to change it in the ReadProperties and WriteProperties events.[/white]
For more info:
and
give a good deal of information.
Bob