我在我的应用程序中运行时创建了一个带有一些按钮的表单,我意识到一些困扰我的东西,我无法想象自己或互联网上的任何地方。
请查看以下代码。
procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
i: Integer; B: TButton;
begin
for i := 1 to 4 do
begin
B := TButton.Create(frmTest);
B.Parent := frmTest;
B.SetBounds(250,(70+(30*i)),75,25);
B.Caption := 'Button' + IntToStr(i);
B.Visible := True;
end;
end;
所以我只是在运行时在特定位置的表单上创建了四个按钮。到目前为止这么好吧?
但现在让我们想象一下,我想将第一个按钮的Caption属性更改为“HotPotato”?我现在如何引用第一个按钮,因为我只使用一个变量来创建这些按钮?我被告知要将这些对象存储在TButton数组中,或者更好地存储在TObjectList中,这些都是解决这个问题的好方法。但后来我想到了一个问题!
这些按钮位于内存中的哪个位置?我是否可以在不使用数组或对象列表的情况下引用它们?
跟踪多个类似对象的常规方法是使用数组。
procedure TfrmTest.CreateFourButtons(Sender: TObject);
var
i: Integer;
B: TArray<TButton>; //or array of TButton for older versions
begin
SetLength(B, 4);
for i := 0 to 3 do begin
B[i] := TButton.Create(frmTest);
B[i].Parent := frmTest;
B[i].SetBounds(250,(70+(30*i)),75,25);
B[i].Caption := 'Button' + IntToStr(i);
B[i].Visible := True;
end;
B[0].Caption:= 'HotPotato';
end;
当在表单上放置按钮时,这不是严格需要的,表单已经使用列表来跟踪放置在其上的子控件,但是您需要某种方式来区分不同的按钮。
您可以使用tag
属性:
for i := 1 to 4 do begin
B := TButton.Create(frmTest);
B.Parent := frmTest;
B.Tag:= i;
...
end;
//This will get inefficient if there are many controls on a form.
for var C in frmTest.Controls do begin //10.3 syntax.
if (C is TButton) and (C.tag = 1) then C.Caption:= 'HotPotato'
end;
button
是一个对象,因此它位于堆上。如果你失去了它的参考,你将再也找不到它。但是,如果它被放置在父控件上,那么该父控件将跟踪它,并且您始终可以使用FindChildControl
或表单的Controls
列表来获取它。
FindChildControl
按名称搜索。这需要您设置控件的名称,否则它将不起作用。
var B:= frmTest.FindChildControl('Button1');
注意:FindChildControl仅定位控件的直接子项。它无法找到控件的一个控件的子控件。
如果按钮位于子面板中,则定位儿童可能会变得复杂。最好使用数组或列表来跟踪一系列按钮。