如何在运行时在 Firemonkey 中创建和销毁 TGrid — Android 和 iOS App Dev
How to Create and Destroy TGrid at Runtime in Firemonkey — Android and iOS App Dev
我有一个在运行时创建的 TGrid。该过程要求我在单击“添加项目并刷新”按钮重新创建之前销毁 TGrid。我注意到,如果我在重新创建 TGrid 之前不销毁它,那么沉重的开销会导致我的应用程序冻结超过 8 次或更多次。
我尝试了以下代码但无济于事:
procedure TformMain.AddItemRefreshClick(Sender: TObject);
var
TGrid1 : TTGrid;
begin
if Assigned(TGrid1) then
begin
TGrid1.DisposeOf;
{TGrid1.Free; Tried this also but not working}
{TGrid1 := nil; Tried this also but not working}
end;
TGrid1 := TTGrid.Create(formMain);
With TGrid1 do
begin
Parent := formMain;
Align := TAlignLayout.Client;
Margins.Top := 5;
Margins.Left := 5;
Margins.Right := 5;
Margins.Bottom := 5;
ScrollBars.Visible := True;
Header.Format.Font.Size := 11;
Cells.Format.Font.Size := 11;
TabOrder := 0;
end;
end;
我在地址处遇到访问冲突...听起来是个错误!
有没有更简单的方法可以在运行时创建和销毁像 TGrid 这样的可视化组件?
您必须使用非局部变量来存储网格,以便在调用此方法之间保留其地址。
目前,TGrid1
是一个局部变量。这实质上意味着它是每次调用例程时创建的变量。它的值不会在两次调用之间保存。而在Delphi中,非托管类型的局部变量没有被初始化,所以这基本上是一个随机指针。使用它非常危险! (而且 Assigned
对你没有帮助,因为随机指针很可能是非零的,因为它是......好吧,随机的。)
(顺便说一句,变量名 TGrid1
非常令人困惑,因为它以 T
开头。通常只有类型名称以 T
开头。)
所以改为在您的表单中添加一个私有字段 class:
private
FMyGrid: TGrid;
(我不知道class这个名字是:在你的Q里,你把TTeeGrid
和TTGrid
都写了。)
那你可以做
procedure TformMain.AddItemRefreshClick(Sender: TObject);
begin
// Free old grid
FreeAndNil(FMyGrid);
// Create new grid
FMyGrid := TGrid.Create(formMain);
with FMyGrid do
begin
Parent := formMain;
Align := TAlignLayout.Client;
Margins.Top := 5;
Margins.Left := 5;
Margins.Right := 5;
Margins.Bottom := 5;
ScrollBars.Visible := True;
Header.Format.Font.Size := 11;
Cells.Format.Font.Size := 11;
TabOrder := 0;
end;
end;
FreeAndNil(FMyGrid)
基本上做 FMyGrid.Free
并且还将指针设置为 nil
这样你就不会以悬空指针结束,以防 TGrid.Create
构造函数应该引发异常。
此外,不需要 if Assigned(FMyGrid) then
部分,因为 FMyGrid.Free
会进行检查。
还要注意 FMyGrid
现在是 class 的成员,因此它从一开始就被初始化为 nil
。
我有一个在运行时创建的 TGrid。该过程要求我在单击“添加项目并刷新”按钮重新创建之前销毁 TGrid。我注意到,如果我在重新创建 TGrid 之前不销毁它,那么沉重的开销会导致我的应用程序冻结超过 8 次或更多次。
我尝试了以下代码但无济于事:
procedure TformMain.AddItemRefreshClick(Sender: TObject);
var
TGrid1 : TTGrid;
begin
if Assigned(TGrid1) then
begin
TGrid1.DisposeOf;
{TGrid1.Free; Tried this also but not working}
{TGrid1 := nil; Tried this also but not working}
end;
TGrid1 := TTGrid.Create(formMain);
With TGrid1 do
begin
Parent := formMain;
Align := TAlignLayout.Client;
Margins.Top := 5;
Margins.Left := 5;
Margins.Right := 5;
Margins.Bottom := 5;
ScrollBars.Visible := True;
Header.Format.Font.Size := 11;
Cells.Format.Font.Size := 11;
TabOrder := 0;
end;
end;
我在地址处遇到访问冲突...听起来是个错误!
有没有更简单的方法可以在运行时创建和销毁像 TGrid 这样的可视化组件?
您必须使用非局部变量来存储网格,以便在调用此方法之间保留其地址。
目前,TGrid1
是一个局部变量。这实质上意味着它是每次调用例程时创建的变量。它的值不会在两次调用之间保存。而在Delphi中,非托管类型的局部变量没有被初始化,所以这基本上是一个随机指针。使用它非常危险! (而且 Assigned
对你没有帮助,因为随机指针很可能是非零的,因为它是......好吧,随机的。)
(顺便说一句,变量名 TGrid1
非常令人困惑,因为它以 T
开头。通常只有类型名称以 T
开头。)
所以改为在您的表单中添加一个私有字段 class:
private
FMyGrid: TGrid;
(我不知道class这个名字是:在你的Q里,你把TTeeGrid
和TTGrid
都写了。)
那你可以做
procedure TformMain.AddItemRefreshClick(Sender: TObject);
begin
// Free old grid
FreeAndNil(FMyGrid);
// Create new grid
FMyGrid := TGrid.Create(formMain);
with FMyGrid do
begin
Parent := formMain;
Align := TAlignLayout.Client;
Margins.Top := 5;
Margins.Left := 5;
Margins.Right := 5;
Margins.Bottom := 5;
ScrollBars.Visible := True;
Header.Format.Font.Size := 11;
Cells.Format.Font.Size := 11;
TabOrder := 0;
end;
end;
FreeAndNil(FMyGrid)
基本上做 FMyGrid.Free
并且还将指针设置为 nil
这样你就不会以悬空指针结束,以防 TGrid.Create
构造函数应该引发异常。
此外,不需要 if Assigned(FMyGrid) then
部分,因为 FMyGrid.Free
会进行检查。
还要注意 FMyGrid
现在是 class 的成员,因此它从一开始就被初始化为 nil
。