Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

User Control Question 2

Status
Not open for further replies.

AndyLee100

Technical User
Jun 26, 2003
174
GB
I have a user control with a label and a text box which I have placed on a form.

When I change the caption in the properties list, the control only shows the changes when I click the main form. It does not dynamically change the caption as I type like it does for the standard label control.

Does anyone know how to achieve this?

Thanks

Andy
 
I Think that it is a little bug in the Control you use. but Why not use the standard Controls?
 
It is a barcode entry control and is needed throught the application so I have created a re-useble user control rather than having to recreate the code each time.

This way it also gives better encapsualtion and all the verifying of the barcode etc can be done from within the user control.

I created the control myself so I dont't think there is a bug in it. I don't mean that in a boasting way I just think that there is an event that i am maybe missing that fires when you change the caption property from the properties box.

Andy
 
If you drop a label on a new ActiveX Control project and place this code in the control
Code:
Option Explicit
Private m_strLabelCaption As String
Private Const mc_strLabelCaption As String = "Not Set"


Private Sub UserControl_InitProperties()
        LabelCaption = mc_strLabelCaption
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
        m_strLabelCaption = PropBag.ReadProperty("LabelCaption", mc_strLabelCaption)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
        Call PropBag.WriteProperty("LabelCaption", m_strLabelCaption, mc_strLabelCaption)
End Sub

Property Get LabelCaption() As String
        LabelCaption = Label1.Caption
End Property

Property Let LabelCaption(ByVal sNew As String)
        Label1.Caption = sNew
        PropertyChanged "LabelCaption"
End Property

add a standard project and set it as the start up project. Drop the user control on the form of the standard project. The caption should change correctly. Hope this helps.[spin]

If you choose to battle wits with the witless be prepared to lose.

[cheers]
 
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
 
Bob,

What can I say but thank you and also sorry.

Thank you for all the effort you have gone to on this and it has helped my understanding.

Sorry for misleading you in what the actual problem is. My control is saving the caption(and another property) between instances.

My question was simply a 'does anyone know why this is' kind of question.

I will try and explain a bit better:

When you place a standard label,command button etc on a form and change the caption property in the properties window, the caption changes as you type. When using a user control is doesnt. You can type the caption but it will not change as you type until you click on the form.

I just wondered if this is how it works and thats it or whether I was missing something.

Thank you for all your efforts and thx also Foada.

Both of you have a star

Cheers

Andy
 
No apology necessary, Andy. I did it for fun. Anyway, as far as what you're looking for, there might be an answer in the VBIDE object, which is used for addins. I looked around, and don't find a way of grabbing events from the Properties window. If you find one, let me know.

Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top