【发布时间】:2021-03-06 07:13:09
【问题描述】:
在设计时从这个布局开始。 (以TLayout、TGridPanelLayout、TText元素为例)
在运行时,我使用 ObjectBinaryToText 将完整的对象结构保存到文件中
但是当使用 ObjectTextToBinary 从文件中加载文件时,我得到了这个结果
为什么子控件没有采用之前保存的 exqct 布局? 文件结构似乎没问题,并且包含使用 IDE 保存表单时描述的所有子控件
这是一段演示问题的代码。
PAS 文件
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.Objects, FMX.Layouts, FMX.Controls.Presentation,
FMX.StdCtrls;
type
TForm1 = class(TForm)
RecTop: TRectangle;
ButtonSave: TButton;
ButtonClear: TButton;
ButtonLoad: TButton;
Layout1: TLayout;
GridPanelLayout1: TGridPanelLayout;
Text1: TText;
Text2: TText;
Text3: TText;
Text4: TText;
procedure ButtonSaveClick(Sender: TObject);
procedure ButtonClearClick(Sender: TObject);
procedure ButtonLoadClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
AppPath: string;
AppDatFile: String;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
System.IOUtils;
procedure TForm1.ButtonSaveClick(Sender: TObject);
var
FileStream : TFileStream;
MemStream : TMemoryStream;
begin
FileStream := TFileStream.Create(AppDatFile, fmCreate);
try
MemStream := TMemoryStream.Create;
MemStream.WriteComponent(Layout1);
MemStream.Position := 0;
ObjectBinaryToText(MemStream, FileStream);
finally
MemStream.Free;
FileStream.Free;
end;
end;
procedure TForm1.ButtonClearClick(Sender: TObject);
var
i: Integer;
begin
for i := pred(Layout1.ChildrenCount) downto 0 do
Layout1.Children[i].Free;
end;
procedure TForm1.ButtonLoadClick(Sender: TObject);
var
FileStream : TFileStream;
MemStream : TMemoryStream;
begin
if FileExists(AppDatFile) then
begin
FileStream := TFileStream.Create(AppDatFile, fmOpenRead);
try
MemStream := TMemoryStream.Create;
ObjectTextToBinary(FileStream, MemStream);
MemStream.Position := 0;
MemStream.ReadComponent(Layout1);
Layout1.Align:= TAlignLayout.Client;
finally
MemStream.Free;
FileStream.Free;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
AppPath:= TPath.GetLibraryPath;
AppDatFile:= TPath.Combine(AppPath, 'SaveLoadLayout.dat');
end;
end
FMX 文件
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 RecTop: TRectangle
Align = Top
Size.Width = 640.000000000000000000
Size.Height = 41.000000000000000000
Size.PlatformDefault = False
end
object ButtonSave: TButton
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 3
Text = 'Save'
OnClick = ButtonSaveClick
end
object ButtonClear: TButton
Position.X = 96.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 2
Text = 'Clear'
OnClick = ButtonClearClick
end
object ButtonLoad: TButton
Position.X = 184.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 1
Text = 'Load'
OnClick = ButtonLoadClick
end
object Layout1: TLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 439.000000000000000000
Size.PlatformDefault = False
TabOrder = 4
object GridPanelLayout1: TGridPanelLayout
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 439.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
ColumnCollection = <
item
Value = 50.000000000000000000
end
item
Value = 50.000000000000000000
end>
ControlCollection = <
item
Column = 0
Control = Text1
Row = 0
end
item
Column = 1
Control = Text2
Row = 0
end
item
Column = 0
Control = Text3
Row = 1
end
item
Column = 1
Control = Text4
Row = 1
end>
RowCollection = <
item
Value = 50.000000000000000000
end
item
Value = 50.000000000000000000
end>
object Text1: TText
Align = Client
Size.Width = 320.000000000000000000
Size.Height = 219.500000000000000000
Size.PlatformDefault = False
Text = 'Text1'
end
object Text2: TText
Align = Client
Size.Width = 320.000000000000000000
Size.Height = 219.500000000000000000
Size.PlatformDefault = False
Text = 'Text2'
end
object Text3: TText
Align = Client
Size.Width = 320.000000000000000000
Size.Height = 219.500000000000000000
Size.PlatformDefault = False
Text = 'Text3'
end
object Text4: TText
Align = Client
Size.Width = 320.000000000000000000
Size.Height = 219.500000000000000000
Size.PlatformDefault = False
Text = 'Text4'
end
end
end
end
【问题讨论】:
-
也许您会编辑您的问题以添加 .pas 和 .fmx 文件,以便有兴趣的人可以测试?
-
StackOverflow 的要求之一是问题必须是自包含的,即不允许链接到可能会失效的外部站点。因此,请编辑您的问题以包含 minimal reproducible example,包括 .fmx 和 .pas 文件。请专注于最小的问题,这仍然会重现问题。
-
好吧,我尽力用截图来说明我的问题。大多数代码已经在那里理解我的问题。按照建议在问题中添加更多内容会使阅读变得更加困难
-
当问题与 UI 布局有关时,提供屏幕截图是可以的,就像您的情况一样。两个屏幕截图就足够了:预期和失败。但是,屏幕截图不显示 UI 的结构,例如父子关系,尤其不是个人属性设置。您的问题可能与这些细节有关。根据您模糊的描述,我已经尝试过我的看法,而且效果很好。显然我无法重现您的设置。因此,提供minimal reproducible example 非常重要,具体包括
.fmx文件。 -
感谢 .pas 和 .fmx 文件。我能够重现该问题。代码创建的数据文件并不完全正确:ControlCollection 具有“Control = Form1.Text1”项,而 .fmx 具有“Control = Text1”。当我手动修复数据文件以删除“Form1.”时,它可以正常工作。所以这是 WriteComponent 的罪魁祸首。它看起来很困惑,因为它不知道 Form1 并将其视为外部引用。 [还] 不知道如何在 WriteComponent 中解决这个问题。 [临时] 解决方案是在创建数据文件之后或加载之前对其进行修复。
标签: delphi firemonkey delphi-10.4-sydney