如何创建控件数组?

时间:2009-08-02 02:48:24

标签: delphi

我必须创建一个数组并将所有控件放在那里以便访问它们。这是一个简短的例子:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    const Test:Array[0..2] of TButton = (Button1,Button2,Button3);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

end.

未声明的标识符'Button1'在我声明我的数组的行。但它在上面声明了三行。

问题出在哪里,如何将所有控件放在数组中?

修改

感谢您的回答,但我遇到了问题:

 var TestA:TObjectList<TButton>;

 var index:TComponent;
 begin
 TestA := TObjectList<TButton>.Create(false);
   for index in Form7 do
     if pos(index.name, 'Button') = 1 then
       TestA.add(TButton(index));

 TestA[0].Caption := 'Test'; //Exception out of range.

6 个答案:

答案 0 :(得分:4)

您可能无法像这样在数组常量中引用表单的公共属性。请尝试在表单构造函数/ OnCreate事件中执行此操作。

procedure TForm1.FormCreate(Sender: TObject);
begin
  Test[0] := Button1;
  Test[1] := Button2;
  Test[2] := Button3;
end;

答案 1 :(得分:4)

Ben是对的。您无法在表单设计器中设置控件数组。但是如果你有110张图片,对于这种特殊情况,你可以将它们放入TImageList组件并将其图像集合视为一个数组。

如果你有一堆更正常的控件,比如按钮,你必须创建一个数组并在代码中加载它们。有两种方法可以做到这一点。对于小阵列来说,简单的方法是Ben的答案。对于大型控制集或经常更改的控件集(例如,您的设计尚未完成),只要您确保为它们提供所有序列名称(Button1,Button2,Button3 ......),您就可以尝试一些像这样:

var
  index: TComponent;
  list: TObjectList;
begin
  list := TObjectList.Create(false); //DO NOT take ownership
  for index in frmMyForm do
    if pos('Button', index.name) = 1 then
      list.add(index);
   //do more stuff once the list is built
end; 

(如果您正在使用D2009,请使用TObjectList<TComponent>或更具体的内容。)根据上面的代码构建列表,然后编写一个排序函数回调,根据名称对它们进行排序用它来排序列表,你就得到了你的“阵列”。

答案 2 :(得分:2)

此函数将遍历指定容器上的所有控件,如特定的TPanel甚至整个表单,并使用TImage控件填充指定的TObjectList。

procedure TForm1.AddImageControlsToList(AParent: TWinControl; AList: TObjectList; Recursive: boolean);
var 
  Index: integer;
  AChild: TControl;
begin
  for Index := 0 to AParent.ControlCount - 1 do
  begin
    AChild := AParent.Controls[Index];
    if AChild is TImage then // Or whatever test you want to use
      AList.Add(AChild)
    else if Recursive and (AChild is TWinControl) then
      AddImageControlsToList(TWinControl(AChild), AList, True);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Call like this or similar to get your list of images
  // (assumes MyImageList is declared in Form)
  MyImageList := TObjectList.Create(False);
  AddImageControlsToList(Self, MyImageList, True);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  // Destroy the list
  FreeAndNil(MyImageList);
end;

答案 3 :(得分:1)

这个怎么样?

procedure TForm1.FormCreate(Sender: TObject);
begin
  for b := 1 to 110 do
    Test[b] := FindComponent('Button' + IntToStr(b)) as TButton;
end;

你必须将数组声明为变量而不是常量,它必须从1到110而不是0到109,但这没问题。

答案 4 :(得分:1)

我一直使用它 - 它简单而快速(尽管Wheeler先生的评论) - 将maxbuttons声明为常量

无功   Form1:TForm1;  pbutton:^ tbutton的数组[1..maxbuttons];

实施

{$ R * .dfm}

程序TForm1.Button1Click(发件人:TObject);

(*退出*)

var k:integer;

开始

表示k:= 1到maxbuttons do dispose(pbutton [k]);

接近;

端;

程序TForm1.FormActivate(发件人:TObject);

var k:integer;

开始

(*注意按钮必须按顺序为Button1,Button2等,或者你需要  手动分配它们,例如pbutton [1] ^:= exitbtn etc *)

表示k:= 1到maxbuttons

开始

new(pbutton[k]);

pbutton[k]^:= tbutton(FindComponent('Button'+IntToStr(k)));

端;

端;

procedure TForm1.ButtonMouseDown(Sender:TObject; Button:TMouseButton;   Shift:TShiftState; X,Y:整数);

var k:整数;       B:布尔;

开始 B:= FALSE; K:= 1;

while(k <= maxbuttons)和(而不是b)

开始

如果pbutton [k] ^ =发送者然后(注意发件人指示单击了哪个按钮

begin

  { found it so do something}

  b:=true;

end;

k:=k+1;

端;

端;

答案 5 :(得分:1)

试试这个 VAR          种皮:TObjectList;

 index:TComponent;
begin
   TestA := TObjectList<TButton>.Create(false);
   try
     for index in Form7 do
       if (pos is TButton) OR {or/and} (pos.tag and 8=8) then
         TestA.add(TButton(index));
     if TestA.Count>0 then //Fix:Exception out of range.
       TestA[0].Caption := 'Test'; 
    finally
      TestA.Free; 
    end;
end;