How a TList can get the input value from a Frame's TEdit/TCombobox

252 Views Asked by At

The Main form contains TTabControl which can create some tabs, dynamically. Whenever I add a new tab, a frame is created and add into the new tab. And finally, I will save all these TTabItem into a TList.

TForm1 = class(TForm)
  TabControl1: TTabControl;

procedure TForm1.AddNewTab;
var
  profileFrame :TProfileFrame;
begin
  profileFrame := TProfileFrame.Create(Self);

  //TabItem
  TabItem := TabControl1.Add();
  inc(tab_name_Count);
  tabItem.Text := tab_name_Count.ToString;
  //
  profileFrame.Parent := tabItem;
  tablist.Add(TabItem);
end;

And this is my frame:

TProfileFrame = class(TFrame)
 Name: TEdit;
 Gender: TComboBox;

Finally, how can I get the (Name) and (Gender) value in the frame, and print it out in main form? If let say i created 4 tabs, each tabs has its own frame, how can i get the value from different frame?? Im super confuse and new to Delphi.

1

There are 1 best solutions below

0
On BEST ANSWER

The main problem is your frames' variable are procedure local variable.

I see different ways to solve your problem.

First: using TObjectList:

uses ..., System.Generics.Collections;

TForm1 = class(TForm)
  TabControl1: TTabControl;
private
  FFrames:TObjectList<TProfileFrame>;    

procedure TForm1.AddNewTab;
var
  profileFrame :TProfileFrame;
begin
  //TabItem
  TabItem := TabControl1.Add();
  profileFrame := TProfileFrame.Create(TabItem); 
  inc(tab_name_Count);
  tabItem.Text := tab_name_Count.ToString;
  profileFrame.Parent := tabItem;
  if not assigned(FFrames) then
    FFrames := TObjectList<TProfileFrame>.Create(false); //we don't need ObjectList to own Frame, I suppose, so we have to pass `false` into Create method
  FFrames.Add(profileFrame);
  tablist.Add(TabItem);
end;

//Just to demonstrate how to get value from frame
function TForm1.GetGenderFromFrame(ATabItem:TTabItem):String;
var i:integer;
begin
  result := '';
  if FFrames.Count > 0 then
  for i := 0 to FFrames.Count - 1 do
    if FFrames[i].TabItem = ATabItem then
    result := FFrames[i].Gender.Selected.Text;
end;

Or you can use another way (checked on Delphi 10.1 FMX Project). You have to change your procedure like this:

procedure TForm1.AddNewTab;
var
  profileFrame :TProfileFrame;
begin  
  //TabItem
  TabItem := TabControl1.Add();
  profileFrame := TProfileFrame.Create(TabItem);
  inc(tab_name_Count);
  tabItem.Text := tab_name_Count.ToString;
  //
  profileFrame.Parent := tabItem;
  tablist.Add(TabItem);
end;

Now your frame has owner: TabItem. And TabItem has components. We can use it:

function TForm1.GetGenderFromFrame(ATabItem:TTabItem):String;
var i:integer;
begin
  result := '';
  if ATabItem.ComponentCount > 0 then
  for i := 0 to ATabItem.ComponentCount - 1 do
    if ATabItem.Components[i] is TProfileFrame then
    result := (ATabItem.Components[i] as TProfileFrame).Gender.Selected.Text;
end;

P.S. You can use for ... in ... do instead of for ... to ... do, it can be better, but it's up to you.