I have a TPanel on a delphi form, I want to copy all the TLabels parented with this TPanel when i press a button and put them in other panel. Is there a way to do that? Thanks.
-
If I were you I would write a routine that populates a panel with new labels and avoid using the dfm file. So I wouldn't invent duplicating logic, I'd write one bit of code that synthesised the requisite labels inside a specified container. – David Heffernan Mar 28 '11 at 18:14
2 Answers
To copy
the TLabel controls from one TPanel to another you can use something like this
Procedure CopyLabels(ParentControl,DestControl:TWinControl);
var
i : integer;
ALabel : TLabel;
begin
for i := 0 to ParentControl.ControlCount - 1 do
if ParentControl.Controls[i] is TLabel then
begin
ALabel:=TLabel.Create(DestControl);
ALabel.Parent :=DestControl;
ALabel.Left :=ParentControl.Controls[i].Left;
ALabel.Top :=ParentControl.Controls[i].Top;
ALabel.Width :=ParentControl.Controls[i].Width;
ALabel.Height :=ParentControl.Controls[i].Height;
ALabel.Caption:=TLabel(ParentControl.Controls[i]).Caption;
//you can add manually more properties here like font or another
end;
end;
and use like this
CopyLabels(Panel1,Panel2);
you can use the RTTI
too, to copy the properties from a control to another, but as you does not specify your Delphi version only i show a simple example.

- 134,889
- 20
- 356
- 483
TPanel is a container of Components. It has a list of its child components in its Controls property. You may iterate over this list to get access to its children.
At the press of the button your code has to
iterate on the Controls list of Panel1
check if the control is a TLabel
change the Parent property of the TLabel to be Panel2
something like this
for i := 0 to Panel1.ControlCount - 1 do
if Panel1.Controls[i] is TLabel then
(Panel1.Controls[i] as TLabel).Parent:=Panel2;
But, wait!, this will not work. Why? Because doing this change 'on the fly' you will be changing the very same list you are iterating over.
So, you have to save the labels to be moved in a temporary list. Something like this...
var
i:integer;
l:TObjectList;
begin
l:=TObjectList.Create;
l.ownsObjects:=False;
for i := 0 to Panel1.ControlCount - 1 do
if Panel1.Controls[i] is TLabel then
l.add(Panel1.Controls[i]);
for i:= 0 to l.Count-1 do
(l[i] as TLabel).Parent:=Panel2;
l.Free;
end;

- 28,486
- 9
- 71
- 95
-
2
-
it looks like this code will only move and not copy (duplicate) the labels, they will disappear on the first panel – mjn Mar 28 '11 at 18:13
-
5Anyway, if you are moving, the normal way to do it is to run the loop downwards, e.g. `for i := Panel1.ControlCount - 1 downto 0 do`. Then it doesn't matter if you take things out of the list because it only affects indices of the items you have already dealt with. – David Heffernan Mar 28 '11 at 18:13
-
@RRUZ ooops you are right. I misread the OP, "put them on another panel", sorry for the confusion – PA. Mar 28 '11 at 19:20