Locking and Unlocking the Bound Controls (AKA "How to Eliminate the Tag Property!")
Of course, one way we could notify our control which controls are associated with it is via the
Tag property of the control. You may recall that in our data class, we just added a unique number to the tag property of each control that used our class. We will be able to eliminate that here by thinking a bit about what information is available to an ActiveX control. Our control knows its own name, so it will just check the
DataSource property of each control in the host collection. If the
DataSource name is equal to our control name, we know it is bound! This is how our control knows which controls to lock or unlock.
Remember that we only permit the user to edit data when they press the Edit button, or add when the Add New button is pressed. It is only then that we unlock the controls for data entry. This routine handles that task for us.
Try It Out - Coding the lockTheControls Subroutine
1. Add another sub routine to your control called
lockTheControls with a Boolean parameter called
bLocked). Passing in either True or False as the parameter will lock or unlock each of the controls that are bound to our ActiveX control.
Private Sub lockTheControls(bLocked As Boolean) On Error Resume Next Dim iindx As Integer With m_form For iindx = 0 To .Controls.Count - 1 If (.Controls(iindx).DataSource = Ambient.DisplayName) Then If (TypeOf .Controls(iindx) Is TextBox) Then If (bLocked) Then .Controls(iindx).Locked = True .Controls(iindx).BackColor = vbWhite Else .Controls(iindx).Locked = False .Controls(iindx).BackColor = vbYellow End If End If End If Next End With End Sub
How It Works
It is worth pointing out that our private variable,
m_form of type Object, holds the reference to the current host of our control. This property will be set automatically by our control. Once our control knows about its host, this routine can just iterate through the collection of controls on the host form.
With m_form For iindx = 0 To .Controls.Count - 1 If (.Controls(iindx).DataSource = Ambient.DisplayName) Then
Now this is a cool tip. Remember in the data class, we had to use the
Tag property to determine which controls were linked to our class? This meant that the user had to set the
Tag property in our class and then add that same number to the
Tagproperty of each control that used the class. Well, it was simple, but still another step for the programmer not to forget.
Here, as our control iterates through the controls, it looks at the name of the
DataSource. If our control is bound, it will have the name of our control tucked away there. We just check that name against the
Ambient.DisplayName of our control. If they match, we know that the control is bound. Here we are able to deduce yet another piece of information, thus eliminating the user of our control to keep track of something. These are the little things that we always want to be on the look out for. By adding this little feature, we just made our control that much easier to use!
Containers, such as our host form, provide ambient properties that give controls hints about how they can best display themselves and other tidbits of information about the container. For example, the
ambient.BackColor property tells a control what color it might set its own
BackColor property so the control could read it and automatically blend in with the back color of the container.
Visual Basic makes these various ambient properties available to your ActiveX control through an AmbientProperties object. The ambient property of your
UserControl returns a reference to the AmbientProperties object. One of the ambient properties is the value of the
DisplayName. By reading the
DisplayName, our control can identify the name of the specific data control. Remember that a single class can have several objects instantiated from it. The programmer will name each instance of the control with a different name. Our control needs to know which specific object it is working on. By reading the
Ambient.DisplayName, we simply find out what the user named this instance of our control. And if the user has two or more instances of our control on the form, we know which one 'this one' is.