Как TList может получить входное значение из TEdit/TCombobox фрейма

Основная форма содержит TTabControl, которая может динамически создавать несколько вкладок. Всякий раз, когда я добавляю новую вкладку, создается фрейм и добавляется в новую вкладку. И, наконец, я сохраню все эти TTabItem в 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;

А это мой кадр:

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

Наконец, как я могу получить значения (Имя) и (Пол) во фрейме и распечатать их в основной форме? Если, скажем, я создал 4 вкладки, каждая вкладка имеет свой собственный фрейм, как я могу получить значение из другого фрейма?? Я очень запутался и новичок в Delphi.


person beyond    schedule 04.08.2020    source источник
comment
Вы можете передать ссылку на ваш основной фрейм в динамически создаваемые фреймы или сохранить ссылки на ваши вновь созданные фреймы в вашем основном фрейме (в зависимости от того, каким образом вы хотите общаться).   -  person Danon    schedule 04.08.2020
comment
tabcontrol, фрейм, кнопка добавления, имя, пол... Почему две разные учетные записи работают над одним и тем же проектом? Связано: Как получить пользовательский ввод из фрейма и сохранить в текстовый файл?   -  person AmigoJack    schedule 04.08.2020


Ответы (1)


Основная проблема заключается в том, что переменная ваших фреймов является локальной переменной процедуры.

Я вижу разные пути решения вашей проблемы.

Первый: используя 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;

Или можно использовать другой способ (проверено на Delphi 10.1 FMX Project). Вы должны изменить свою процедуру следующим образом:

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;

Теперь у вашего фрейма есть владелец: TabItem. И TabItem имеет компоненты. Мы можем использовать его:

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. Вы можете использовать for ... in ... do вместо for ... to ... do, это может быть лучше, но решать вам.

person mrNone    schedule 04.08.2020