Reputation: 35
I have a TStackPanel which I want to add a number of frames into at runtime. The number may vary each time the form is opened.
There seems to be limited information about TStackPanel around, and the examples I can find are in languages other than Delphi.
I have a loop that creates the frame, gives it a unique name and then adds it to the TStackPanel:
for i := 0 to 10 do
begin
mfSubFrame[i] := TMyFrame.Create(Application);
mfSubFrame.Name := name_array[i];
StackPanel1.InsertComponent(mfSubFrame[i]);
end;
This does not put anything in the stack panel. If I change the SP line to:
StackPanel1.InsertControl(mfSubFrame[i]);
then I do get a frame in the SP. It is the last one of the loop as I can tell by the name, the others may be hidden behind it but I can't tell. They are certainly not stacked horizontally like they should.
I have tried various other things like setting the parent of the frames to be the SP, and had a look at things like:
StackPanel1.Components.InsertComponent(mfSubFrame[i]);
and other sub-methods, but had no luck so far.
I suspect it may require a combination of statements, like add a control item as well as the actual component, but as I am working on the basis of trial and error it could be a long time before I stumble on the right combination.
Upvotes: 1
Views: 1139
Reputation: 598279
InsertComponent()
changes a component's Owner
, which has no effect on visual display. You are creating each frame with Application
as its Owner
, and then changing its Owner
to StackPanel1
. You should assign the desired Owner
when calling the component's constructor.
InsertControl()
changes a control's Parent
, which does affect visual display. You are creating each frame without a Parent
, and then changing its Parent
to be StackPanel1
. You should be using the actual Parent
property, not calling InsertControl()
directly.
That being said, TStackPanel
has a ControlCollection
property that you are not doing anything with. That collection manages the actual stacking.
If needed 1, for each frame, try calling StackPanel1.ControlCollection.Add()
, and then assigning the frame to the TStackPanelCollectionItem.Control
property.
1: I don't have the source code for TStackPanel
to look at, but I suspect TStackPanel
probably handles this automatically for UI controls dropped onto it at design-time, but you might need to perform it manually for controls that you create dynamically at runtime. I'm not sure.
Upvotes: 2
Reputation: 109148
I have never used the TStackPanel
before, but it seems like you can add controls to it exactly the same way you add controls to any other windowed control: just create the control and assign its Parent
.
For example,
for var i := 1 to 10 do
begin
var Memo := TMemo.Create(Self);
Memo.Parent := StackPanel1;
end;
will add ten memo controls (all owned by Self
) to StackPanel1
. There is no need to name the controls; referring to components by string name at runtime is an antipattern. (So is using FindComponent
.)
Upvotes: 2