如何在运行时将项目添加到 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 控件在设计时加入它,但您可能 需要为您在运行时动态创建的控件手动执行它。我不确定。