Identical components on Delphi form: Components array


[ DelphiLand FAQ ] [ Delphi Tutorials ]

Posted by webmaster Guido on December 23, 2002

In Reply to: Identical components on form? posted by Roeland on December 23, 2002

: How can I change the caption of several labels at the same time, after entering something in an edit-box? Of course, I can do it as follows:

: Label1.Caption := Edit1.text;
: Label2.Caption := Edit1.text;
: // and so on...
:
: But can't I do this by putting the SAME label several times on the Delphi form? Because otherwise, if I want to change the text at 100 places at the same moment, I have to write 100 lines of code. So the question is: can there be two exactly identical components on a form?
-----------------

Each component on a Delphi form must have a unique name, so the answer to the last question is: no. But there is another solution to your first question.

Each form has a property "Components", which is an array of pointers to the components that are "owned" by the form. So, you loop through each element of TForm.Components, check if the element points to a TLabel component, and if yes, set its caption. If done like this, *all* of the TLabels will get the same caption, but there are ways to differentiate between labels.

Solution 1: Each component has a property called "Tag", in which you can store an integer value. At design time, you could set the Tag to 1 for the labels whose caption you want to change under program control, and leave all the others at 0. Later on, change the label captions as follows:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to ComponentCount - 1 do
    if Components[i] is TLabel then
      if (Components[i] as TLabel).Tag = 1 then
        (Components[i] as TLabel).Caption := Edit1.Text; 
end;

Solution 2: you could differentiate your "special" group of labels from the other labels on the form, by giving them specific names. Two names can not be identical on the same form, but you can start all the names of this group by the same series of characters. For example, call them Group1_01, Group1_02, Group1_03,... and later on check if the component's name starts with an "Group1".

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  CompName: string;
begin
  for i := 0 to ComponentCount - 1 do
    if Components[i] is TLabel then begin
      CompName := (Components[i] as TLabel).Name;
      if Copy(UpperCase(CompName), 1, 6) = 'GROUP1' then
        (Components[i] as TLabel).Caption := Edit1.Text;
    end;
end;


[ DelphiLand FAQ ] [ Delphi Tutorials ]