我正在构建一个非常简单的Firemonkey项目(RadStudio 10.3.3),以测试未来项目的某些布局选项。在过去的VCL中,我使用模式形式。我正在测试的项目在主窗体(Form1)上使用面板(Panel1和Panel2)来嵌入两个其他窗体(Form2和Form3)。这两个嵌入式表单在每个表单上都包含一个列表框(ListBox1)。主窗体上的面板重叠,因此我使用Visibility属性显示所需的嵌入式窗体。所有代码都在主窗体上。
我遇到的问题是,当我在Form2和Form3之间切换时,加载到Form3列表框中的字符串永远不会出现。我在列表框和面板上尝试了重画,在列表框上尝试了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.
Form2如下:
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.
Form3如下:
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(Form1):
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(Form2):
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(Form3):
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时,我确定我缺少一些简单的东西。感谢您提供的所有帮助!
解决方案非常简单。我必须从项目的初始化设置中删除Form2和Form3的CreateForm事件-我这是一个愚蠢的错误。在执行过程中它丢失了对这些表格的引用。
答案 0 :(得分:1)
我能重现该错误的唯一方法是将表单和两个面板之间的父子关系设置为错误。
例如如果Panel2
是Panel1
的子代,我可以重现您描述的错误行为,但是如果它们都是形式的子代,则无法重现该问题。也许您误将第二个面板放在Panel1
上了?在IDE中检查结构窗口。
.fmx
个文件添加到问题中后,编辑
查看提供的Unit1.fmx
,其结尾如下:
object Panel1: TPanel
Align = Center
Size.Width = 640.000000000000000000
Size.Height = 393.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
object Layout1: TLayout
Align = Contents
Size.Width = 640.000000000000000000
Size.Height = 393.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
end
end
没有Panel2
,因为根据Unit1.pas
应该存在。而是有Layout1
作为Panel1
的子级。因此,现在发布的.fmx
文件与您昨天提供的.pas
文件不匹配。但这仍然可以证实我已经说过的话。
如果Panel2
已替换为这种布局,换句话说Panel2
是Panel1
的子代,那么这将完全解释您最初询问的行为。
答案 1 :(得分:1)
好,由于Tom的挫败感(再次,Tom,很抱歉!)和我自己的沮丧,我再次重建了测试应用程序。这次,两个列表框都不会显示字符串。然后,我开始考虑Form2和Form3失去与Form1的连接,因此我调查了Tom询问的.fmx文件。那导致我查看了项目初始化文件,瞧!
program Project1;
uses
System.StartUpCopy,
FMX.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
//Application.CreateForm(TForm2, Form2); <-- NOW COMMENTED OUT
//Application.CreateForm(TForm3, Form3); <-- NOW COMMENTED OUT
Application.Run;
end.
应用程序在启动时正在创建Form2和Form2,然后在代码中创建重复项,从而导致丢失参考。我只是在启动时注释了Form2和Form3行,以防止应用程序创建它们,并且按预期工作。谢谢,汤姆!