我必须创建一个数组并将所有控件放在那里以便访问它们。这是一个简短的例子:
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.
答案 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;