Reputation: 27
I want to refer to a component (using loop) which exists in multiple frames. The component is the same for all frames.
I also have multiple frames (which I instantiate at runtime). The frames I create are named:
frm1, frm2, frm3
Each frame has a multple TabSheets created at runtime named: page_1, page_2, page_3
So, I am currently using:
Tfrm1(FindComponent('page_'+i)).comboBoxAccount
Which means I use FindComponent
with i in a loop to access all comboBoxAccount
in all TabSheets.
The problem is that I have to use casting to make Delphi understand which component I want to access, so I've put Tfrm1( )
in front of FindComponent
.
So, if I want to use casting with a loop what can I do?
I could just use:
Tfrm1(FindComponent('page_'+i)).comboBoxAccount
Tfrm2(FindComponent('page_'+i)).comboBoxAccount
Tfrm3(FindComponent('page_'+i)).comboBoxAccount
but is there a way to loop Tfrm
without writing them one by one?
Upvotes: 0
Views: 1268
Reputation: 596582
page_1
, page_2
, etc are TabSheets, not frames, but you are casting them to frames, which is wrong.
If each frame has multiple TabSheets on it, and each TabSheet has a ComboBox on it, you would not use FindComponent()
at all. You would have to iterate through parent/child Controls[]
lists instead, or use FindChildControl()
.
However, if the frame is the Owner
of the ComboBox (which it would be if the ComboBox is added to the frame at design-time), then you would use FindComponent()
on the frame itself. But you cannot have multiple child components with the same name, so each ComboBox on each TabSheet would need a unique name:
cb := TComboBox(frm1.FindComponent('comboBoxAccount_'+IntToStr(i)));
Repeating for each index of frm1
, then all indexes of frm2
, then frm3
.
If your ComboBox really is named just comboBoxAccount
then I wonder if you really have one parent container that has multiple TabSheets on it, and each TabSheet has a frame on it, and each frame has only one ComboBox named comboBoxAccount
on it. If that is the case, you don't need to do any searching at all, just use your existing object pointers directly:
cb := frm1.comboBoxAccount;
cb := frm2.comboBoxAccount;
cb := frm3.comboBoxAccount;
But if you really want to use a loop, then put the frames into a list, eg:
private
Frames: TList;
...
Frames := TList.Create;
Frames.Add(frm1);
Frames.Add(frm2);
Frames.Add(frm3);
...
for I := 0 to Frames.Count-1 do
begin
// assuming TFrm1, TFrm2, etc do not have a common ancestor holding the ComboBox...
cb := TComboBox(TWinControl(Frames[i]).FindComponent('comboBoxAccount'));
...
end;
Or use an array:
private
// assuming TFrm1, TFrm2, etc do not have a common ancestor holding the ComboBox...
Frames: array[0..2] of TWinControl;
...
Frames[0] := frm1;
Frames[1] := frm2;
Frames[2] := frm3;
...
for I := Low(Frames) to High(Frames) do
begin
cb := TComboBox(Frames[i].FindComponent('comboBoxAccount'));
...
end;
Update: given new information you provided, you can find the ComboBox like this instead:
cb := Tfrm1(PageControl[i].Pages[j].FindChildControl('frame_'+IntToStr(i))).comboBoxAccount;
Your while
loop is creating multiple tabsheets and frames that have the same Name
, which is not valid. I would suggest not naming them at all.
while condition=true do
begin
TabSheet := TTabSheet.Create(PageControl[i]);
TabSheet.Caption := '';
//TabSheet.Name:='tabesheet_'+IntToStr(i);
TabSheet.PageControl := PageControl[i];
TabSheet.PageControl.ActivePageIndex:=0;
{I also create a frame for each TabSheet. In every frame there is the ComboBox that I want to access}
frame := Tfrm1.Create(TabSheet);
//frame.Name:='frame_'+IntToStr(i);
frame.Parent:=TabSheet;
end;
Assuming a frame is the only child of its TabSheet, you can then do this:
cb := Tfrm1(PageControl[i].Pages[j].Controls[0]).comboBoxAccount;
Upvotes: 1