Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

Control Arrays

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.)

Not only are control arrays hard to set up and hard to use, but they don't always work. For at least some of the base classes and some of the events, a control array's events don't fire when they should unless you bend over backward to help them. In those cases, unless the class on which a particular control in the array is based has code for the particular method, the array's method doesn't fire. Don't worry if this doesn't make sense to you—it doesn't make any sense to us, either.

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.

Example

* 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

See Also

CommandGroup, Container, Control, OptionGroup