如何在运行时将项目添加到 TStackPanel
How do you add an item to a TStackPanel at runtime
我有一个 TStackPanel,我想在运行时向其中添加一些帧。每次打开表格时,数字可能会有所不同。
周围关于 TStackPanel 的信息似乎有限,我能找到的例子都是 Delphi 以外的语言。
我有一个创建框架的循环,给它一个唯一的名称,然后将它添加到 TStackPanel:
for i := 0 to 10 do
begin
mfSubFrame[i] := TMyFrame.Create(Application);
mfSubFrame.Name := name_array[i];
StackPanel1.InsertComponent(mfSubFrame[i]);
end;
这不会在堆栈面板中放置任何内容。如果我将 SP 行更改为:
StackPanel1.InsertControl(mfSubFrame[i]);
然后我在 SP 中得到了一个框架。它是循环的最后一个,正如我所知道的那样,其他的可能隐藏在它后面,但我无法分辨。它们肯定没有像应有的那样水平堆叠。
我尝试了各种其他方法,例如将框架的父级设置为 SP,并查看了以下内容:
StackPanel1.Components.InsertComponent(mfSubFrame[i]);
和其他子方法,但到目前为止还没有成功。
我怀疑它可能需要语句的组合,比如添加一个控制项以及实际的组件,但由于我是在反复试验的基础上工作的,所以我可能需要很长时间才能偶然发现正确的组合。
我以前从未使用过 TStackPanel
,但似乎您可以向其添加控件,就像向任何其他窗口控件添加控件一样:只需创建控件并为其分配 Parent
.
例如,
for var i := 1 to 10 do
begin
var Memo := TMemo.Create(Self);
Memo.Parent := StackPanel1;
end;
将向 StackPanel1
添加十个备忘录控件(全部归 Self
所有)。无需命名控件;在运行时通过字符串名称引用组件是一种反模式。 (使用 FindComponent
也是如此。)
InsertComponent()
改变了组件的Owner
,对视觉显示没有影响。您正在使用 Application
作为其 Owner
创建每个帧,然后将其 Owner
更改为 StackPanel1
。您应该在调用组件的构造函数时分配所需的 Owner
。
InsertControl()
更改控件的 Parent
,这确实会影响视觉显示。您正在创建没有 Parent
的每个帧,然后将其 Parent
更改为 StackPanel1
。您应该使用实际的 Parent
属性,而不是直接调用 InsertControl()
。
话虽这么说,TStackPanel
有一个 ControlCollection
属性,您没有对其进行任何操作。该集合管理实际堆叠。
如果需要 1,对于每一帧,尝试调用 StackPanel1.ControlCollection.Add()
, and then assigning the frame to the TStackPanelCollectionItem.Control
属性.
1:我没有 TStackPanel
的源代码可供查看,但我怀疑 TStackPanel
可能会自动处理掉落的 UI 控件在设计时加入它,但您可能 需要为您在运行时动态创建的控件手动执行它。我不确定。
我有一个 TStackPanel,我想在运行时向其中添加一些帧。每次打开表格时,数字可能会有所不同。
周围关于 TStackPanel 的信息似乎有限,我能找到的例子都是 Delphi 以外的语言。
我有一个创建框架的循环,给它一个唯一的名称,然后将它添加到 TStackPanel:
for i := 0 to 10 do
begin
mfSubFrame[i] := TMyFrame.Create(Application);
mfSubFrame.Name := name_array[i];
StackPanel1.InsertComponent(mfSubFrame[i]);
end;
这不会在堆栈面板中放置任何内容。如果我将 SP 行更改为:
StackPanel1.InsertControl(mfSubFrame[i]);
然后我在 SP 中得到了一个框架。它是循环的最后一个,正如我所知道的那样,其他的可能隐藏在它后面,但我无法分辨。它们肯定没有像应有的那样水平堆叠。
我尝试了各种其他方法,例如将框架的父级设置为 SP,并查看了以下内容:
StackPanel1.Components.InsertComponent(mfSubFrame[i]);
和其他子方法,但到目前为止还没有成功。
我怀疑它可能需要语句的组合,比如添加一个控制项以及实际的组件,但由于我是在反复试验的基础上工作的,所以我可能需要很长时间才能偶然发现正确的组合。
我以前从未使用过 TStackPanel
,但似乎您可以向其添加控件,就像向任何其他窗口控件添加控件一样:只需创建控件并为其分配 Parent
.
例如,
for var i := 1 to 10 do
begin
var Memo := TMemo.Create(Self);
Memo.Parent := StackPanel1;
end;
将向 StackPanel1
添加十个备忘录控件(全部归 Self
所有)。无需命名控件;在运行时通过字符串名称引用组件是一种反模式。 (使用 FindComponent
也是如此。)
InsertComponent()
改变了组件的Owner
,对视觉显示没有影响。您正在使用 Application
作为其 Owner
创建每个帧,然后将其 Owner
更改为 StackPanel1
。您应该在调用组件的构造函数时分配所需的 Owner
。
InsertControl()
更改控件的 Parent
,这确实会影响视觉显示。您正在创建没有 Parent
的每个帧,然后将其 Parent
更改为 StackPanel1
。您应该使用实际的 Parent
属性,而不是直接调用 InsertControl()
。
话虽这么说,TStackPanel
有一个 ControlCollection
属性,您没有对其进行任何操作。该集合管理实际堆叠。
如果需要 1,对于每一帧,尝试调用 StackPanel1.ControlCollection.Add()
, and then assigning the frame to the TStackPanelCollectionItem.Control
属性.
1:我没有 TStackPanel
的源代码可供查看,但我怀疑 TStackPanel
可能会自动处理掉落的 UI 控件在设计时加入它,但您可能 需要为您在运行时动态创建的控件手动执行它。我不确定。