A component (or control) array, as the name implies, is nothing more than an array of components. As with any array type variable, you can access an element of an array by index. In case of a component array, an element of the array is a component, like TButton or TLabel.
There are two main reasons for using component arrays in Delphi:
- Accessing (changing properties) and managing (sharing event handlers) a group of component (placed on a form at design time) by index, or
- Accessing and managing a group of components (by index) created at run-time.
In both cases, the idea is to process some code against all the component in the array in some kind of a loop.
In this article, you will learn how to access a group of design-time created components - by storing the components in an array.
Note: if you only want to share an event handler between a group of ("compatible") components, you do *not need* to create an array of components.
An Array of Components Created at Design-TimeSuppose you have placed 4 panels (TPanel controls) on a form and you want to change the background color of all 4 panels in "one" code block. Without the 4 panels being placed in an array, you would need to make a call similar to (to change the background color to red) :
This is not bad, but in some scenarios, you could have, for example, 40 panels. A much better way of accessing all those panels would be to use the loop:
//Suppose there a 4 TPanel components on a form (or any container, of course), named "Panel1", "Panel2", "Panel3" and "Panel4" Panel1.Color := clRed; Panel2.Color := clRed; Panel3.Color := clRed; Panel4.Color := clRed;
In the sample code above, the array variable panels is used to store a reference to 40 TPanel components.
for cnt := 1 to 40 do panels[cnt].Color := clRed;
The panels array would need to be declared as:
panels : array[1..40] of TPanel;
Of course, only declaring the panels array does not store the reference to the 40 panels. You need to find a way to make sure that, for example, panels, returns a TPanel control.
Panels Array ExampleLet's build an example of a component array usage in Delphi. By following the steps provided, you will create an array of 6 panels. For the sake of simplicity, I'll show you how to change the background color of all panels using a loop...
- Drop 6 TPanel components on a form named "MainForm"
- Leave the default names. This results in the 6 panels being named as "Panel1", "Panel2", "Panel3", "Panel4", "Panel5" and "Panel6".
- Declare an array, in the private / interface section of the form declaration:
type TMainForm = class(TForm) ... private panels : array[1..6] of TPanel;
- In order to access the panels (using the array), we first need to store the reference to each panel in the panels array. The form's OnCreate event is a good place to fill the array:
procedure TMainForm.FormCreate(Sender: TObject) ; var cnt : integer; begin for cnt := 1 to 6 do begin panels[cnt] := FindComponent(Format('Panel%d',[cnt])) as TPanel; end; end;
Note: The FindComponent method returns the component in the (MainForm's) Components property array with the name that matches the string used as a parameter.
The 6 panels are named "Panel1" to "Panel6", when for example, the loop variable "cnt" is 4, FindComponent('Panel4') will return the Panel named "Panel4".
Since FindComponent return an object of type TComponent we need to type-cast it to TPanel.
- Drop a TButton (named "PanelColorButton") and a TColorListBox (named ColorListBox1) on the form. Handle the button's OnClick event as:
Note: when you click the button, all the 6 panels will have the background color equal to the one selected in the color list box.
procedure TMainForm.PanelColorButtonClick(Sender: TObject) ; var cnt : integer; begin for cnt := 1 to 6 do begin panels[cnt].Color := ColorListBox1.Selected; end; end;
Note that an element of the panels array is, well, a TPanel object. When you write, for example, "panels." (<- note the dot) you will see all the properties of the TPanel object.
Question: "Do I need to free the memory used by the panels array?
Answer: No. Since panels are placed on the form at design-time, they are owned by the form. When the form gets destroyed, the panels get destroyed also.
That's it for the first article on component arrays. Next time, I'll show you how to manage an array of components created at run-time.