У меня есть очень простой проект Firemonkey (RadStudio 10.3.3), который я создаю, чтобы протестировать определенные варианты макета для будущего проекта. В прошлом с VCL я использовал модальные формы. Тестируемый проект использует панели (Panel1 и Panel2) в основной форме (Form1) для встраивания двух дополнительных форм (Form2 и Form3). Две встроенные формы состоят из одного списка (ListBox1) в каждой форме. Панели на основной форме накладываются друг на друга, поэтому я использую свойство «Видимость», чтобы отобразить нужную встроенную форму. Весь код находится на главной форме.
У меня проблема в том, что когда я переключаюсь между Form2 и Form3, строки, загруженные в список на Form3, никогда не появляются. Я пробовал Repaint в списке и панели, InvalidateRect в списке, SetFocus на панели и т. д., за которыми следуют Application.ProcessMessages. Ничего не работает успешно.
Основной код:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Panel2: TPanel;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
procedure EmbedForm(AParent:TControl; AForm:TCustomForm);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses Unit2, Unit3;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Embed Form2 in Panel1
Application.CreateForm(TForm2, Form2);
EmbedForm(Panel1, Form2);
Panel1.Visible := true;
// Embed Form3 in Panel2
Application.CreateForm(TForm3, Form3);
EmbedForm(Panel2, Form3);
Panel2.Visible := false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Populate ListBox1 on Form2 - the LOAD button
Form2.ListBox1.Items.Add('Hello');
Form2.ListBox1.Items.Add('World');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// Hide Panel1 (Form2) and show Panel2 (Form3)
Panel1.Visible := false;
Panel2.Visible := true;
// Populate ListBox1 on Form3
Form3.ListBox1.Items.Add('Goodbye');
Form3.ListBox1.Items.Add('World');
// Repaint (Here's why I have tried various things to get the listbox strings to show up)
//Panel2.Repaint;
//Form3.ListBox1.Repaint;
//Application.ProcessMessages;
end;
procedure TForm1.EmbedForm(AParent: TControl; AForm: TCustomForm);
begin
while AForm.ChildrenCount>0 do
AForm.Children[0].Parent:=AParent;
end;
end.
Форма2 выглядит следующим образом:
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.ListBox;
type
TForm2 = class(TForm)
ListBox1: TListBox;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
end.
Форма 3 выглядит следующим образом:
unit Unit3;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
FMX.ListBox, FMX.Controls.Presentation, FMX.StdCtrls;
type
TForm3 = class(TForm)
ListBox1: TListBox;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
{$R *.fmx}
end.
Файлы .fmx находятся ниже по запросу.
Unit1.fmx (Форма1):
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnCreate = FormCreate
DesignerMasterStyle = 0
object Button1: TButton
Position.X = 232.000000000000000000
Position.Y = 448.000000000000000000
TabOrder = 1
Text = 'Load'
OnClick = Button1Click
end
object Button2: TButton
Position.X = 328.000000000000000000
Position.Y = 448.000000000000000000
TabOrder = 2
Text = 'Next'
OnClick = Button2Click
end
object Panel1: TPanel
Align = Center
Size.Width = 640.000000000000000000
Size.Height = 393.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
end
object Panel2: TPanel
Position.Y = 43.000000000000000000
Size.Width = 640.000000000000000000
Size.Height = 393.000000000000000000
Size.PlatformDefault = False
TabOrder = 4
end
end
Unit2.fmx (Форма2):
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object ListBox1: TListBox
Align = Center
TabOrder = 0
DisableFocusEffect = True
DefaultItemStyles.ItemStyle = ''
DefaultItemStyles.GroupHeaderStyle = ''
DefaultItemStyles.GroupFooterStyle = ''
Viewport.Width = 200.000000000000000000
Viewport.Height = 200.000000000000000000
end
end
Unit3.fmx (Форма3):
object Form3: TForm3
Left = 0
Top = 0
Caption = 'Form3'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object ListBox1: TListBox
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 1
DisableFocusEffect = True
DefaultItemStyles.ItemStyle = ''
DefaultItemStyles.GroupHeaderStyle = ''
DefaultItemStyles.GroupFooterStyle = ''
Viewport.Width = 196.000000000000000000
Viewport.Height = 196.000000000000000000
end
end
Опять же, Form2 и Form3 содержат только список (Listbox1 на обоих) и никакого дополнительного кода. Я просто запускаю исполняемый файл, нажимаю Button1, чтобы отобразить Hello World, затем нажимаю Button2, чтобы переключать панели и отображать вторую форму и ее список. Поскольку я новичок в Firemonkey, я уверен, что упускаю что-то простое. Спасибо за любую помощь!
Решение было очень простым. Мне пришлось удалить события CreateForm для Form2 и Form3 из настроек инициализации проекта — глупая ошибка с моей стороны. Он терял ссылку на эти формы во время выполнения.
TLayout
в исходной форме, а затем просто назначить родителя этого макета. - person Jerry Dodge   schedule 09.12.2019.fmx
к вашему вопросу. Я также должен подчеркнуть, что я не могу воспроизвести вашу проблему, если панели являются прямыми дочерними элементамиForm1
. Это просто работает так, как вы задумали. - person Tom Brunberg   schedule 10.12.2019Unit1.fmx
TPanel
, а в дочернем элементе этой панели —TLayout
, которого нет вUnit1.pas
. Ото, у тебя вообще нетPanel2
вUnit1.fmx
! Итак,Unit1.fmx
не соответствуетUnit1.pas
. Если вы изменили вторую панель наTLayout
(по предложению Джерри), и эта панель была на месте текущего макета, то это именно то, что я сказал в своем ответе. ЭтотPanel2
был ребенкомPanel1
, а не ребенкомForm1
. Что дает именно то поведение, которое вы описали. Вы согласны? - person Tom Brunberg   schedule 10.12.2019