The documentation for just about every event includes an optional nIndex parameter that "uniquely identifies a control if it is in a control array." At one time, there was even a brief definition of "control array" in Help. But the docs give you no clue why you'd ever want to do this or how to make it work.
Our take is that Control Arrays
were part of the original design of the object model to let you do things like group command buttons. The idea is that each element of an array is a reference to a different object. You can define methods for the array and apply them to the individual members. This would let you, for example, have one Click method that responds to a click on any object referenced in the array. The nIndex parameter tells you which one.
Sounds pretty neat, but the CommandGroup and OptionGroup base classes do pretty much the same thing (though slightly differently).
We suspect that once the design team made it easy to group buttons, Control Arrays
didn't seem quite so urgent, because the team never really finished implementing them. You can create Control Arrays
in coded classes, but not in the Class Designer. The way you have to do things to make them work feels really kludgy. (See the example.)
Among the events affected in various versions of VFP are When, Valid, ErrorMessage and Message. Affected controls include text boxes, edit boxes and spinners. Because we consider Control Arrays
pretty much useless, we haven't compiled an exhaustive list of event/control/version combinations that suffer from this malady.
In addition to all that, as far as we can tell, the Destroy event never fires for control arrays. Destroy fires for the contained objects, but never for the array itself. |
Actually, only half the functionality of Control Arrays
seems useless to us. We do expect to store object references in array properties. What we don't plan to do is define methods for the array—we'll rely on the methods of the underlying objects.
* In order to define event methods for a control array, you
* have to define the form in code. As part of the form class
* definition, you can write methods for the array.
* In this example, the array holds a command button and a
* text box. The Click event has code.
DEFINE CLASS TestForm AS FORM
* define the control array
DIMENSION aControls[2]
PROCEDURE Init
* Here's where we can add the controls to the array.
This.AddObject("aControls[1]", "CommandButton")
This.AddObject("aControls[2]", "TextBox")
This.aControls[1].Visible = .T.
This.aControls[2].Visible = .T.
This.aControls[2].Top = 25
ENDPROC
PROCEDURE aControls.Click
* Here's the Click method that fires for any object
* in the array.
LPARAMETERS nIndex
WAIT WINDOW "You clicked on " + This.Name + ;
"["+PADL(nIndex,2)+"]"
ENDPROC
ENDDEFINE