创建表单 // Tabsheet // 访问表单上的方法
Create Form // Tabsheet // access Methods on Form
我正在编写这样的应用程序:
有一个带有 PageControl 的主窗体,
在页面控件中,我创建了 Tabsheets,
在 Tabsheets 中,放置了表单。
这很有帮助,因为用户可以多次创建一种类型的表单,就像在多个选项卡中打开的标准 pdf 查看器一样,但显示不同的数据,本质上是相同的表单。
这个效果很好,很有用!不幸的是,一些重要的东西不起作用,这就是问题所在:
这段代码可以正常工作:
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'Hello';
end;
但是,如果我想改为调用方法,标题将会改变,如下所示:
Procedure changeLabel(str : String);
Begin
Form1.Label1.Caption := str;
End;
procedure TForm1.Button1Click(Sender: TObject);
begin
changeLabel('Hello');
end;
我在 Form1 遇到访问冲突。Label1.Caption := str;在程序中
这是我创建表单的方式:
procedure TfrmPage.CDMA1Click(Sender: TObject);
var
TabSheet: TTabSheet;
frmTest : TForm;
begin
TabSheet := TTabSheet.Create(PageControl1);
TabSheet.Caption := 'kjklhhj';
TabSheet.PageControl := PageControl1;
frmTest := TForm1.Create(Nil);
frmTest.Show;
frmTest.Parent := TabSheet;
end;
我按照大家所说的做了一切:another Whosebug question
我的问题,新创建的固定到 Tabsheet 的表单如何在不抛出异常的情况下访问它自己的过程?另一件可能很重要的事情:当我有 delphi Auto-Create 表单时,没有访问冲突,但该方法对表单没有任何作用,所以我认为该过程可能会更改错误表单上的内容,一个尚未创建的(提供 AV),而不是我刚刚创建的那个,或者应用程序没有在我的新表单上调用该方法,而是在尚未创建该表单的地方调用一个。
如果我 auto-create 表单,调用过程可能会更改应用程序启动时创建的表单上的标签,而不是新表单..
任何帮助将不胜感激,因为我已经谷歌搜索了几个小时但对这个问题没有真正的帮助
提前致谢:)
如果您打算创建 TForm1
class 的多个实例,那么不 auto-create Form1
是正确的。事实上,您应该完全删除 Form1: TForm1
声明以减少出错的风险。
您可能希望保留对您创建的表单的引用 f.ex。在 TList
中,可能由 TfrmPage
实例托管,具体取决于 TfrmPage
是什么。 (见下文关于 AV 的讨论)
访问冲突
当您在 TfrmPage.CDMAClick()
中创建 TForm1
的实例时,您将创建的表单的引用分配给局部变量 frmTest
,然后将其显示在标签表中。您可以单击 Button1
并更改 Label1
的标题。但是,当您调用 ChangeLabel
过程时,您声明
Form1.Label1.Caption := str;
但是 Form1
变量从未被分配,因此是 nil
并且 AV 被触发。现在,由于您将表单引用分配给 TfrmPage.CDMAClick()
中的本地 frmTest
变量,您实际上不再对表单有任何引用,也无法访问它(实际上,因为您将它作为标签表的父级,您可以在选项卡控件中搜索它)。这就是为什么我建议在列表中保留对您创建的表单的引用。然后您可以在需要时通过该列表访问表单。
My Question, how can the newly created form, pinned to the Tabsheet,
access its own procedures without throwing exceptions?
您始终可以从 object 本身访问 object 的方法、字段和属性,而无需使用引用变量。事实上,你永远不应该在 object:
中使用 objects 引用变量
Label1.Caption := 'Whatever'; // correct from within the form
有时可能需要在 object 中使用引用,为此您可以使用 self
f.ex.:
self.Label1.Caption := 'Whatever'; // self can be used if needed
从外部 method/procedure/function 您需要使用对 object
的引用
Form1.Label1.Caption := 'Whatever'; // assuming Form1 has been assigned
我正在编写这样的应用程序:
有一个带有 PageControl 的主窗体, 在页面控件中,我创建了 Tabsheets, 在 Tabsheets 中,放置了表单。
这很有帮助,因为用户可以多次创建一种类型的表单,就像在多个选项卡中打开的标准 pdf 查看器一样,但显示不同的数据,本质上是相同的表单。
这个效果很好,很有用!不幸的是,一些重要的东西不起作用,这就是问题所在:
这段代码可以正常工作:
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := 'Hello';
end;
但是,如果我想改为调用方法,标题将会改变,如下所示:
Procedure changeLabel(str : String);
Begin
Form1.Label1.Caption := str;
End;
procedure TForm1.Button1Click(Sender: TObject);
begin
changeLabel('Hello');
end;
我在 Form1 遇到访问冲突。Label1.Caption := str;在程序中
这是我创建表单的方式:
procedure TfrmPage.CDMA1Click(Sender: TObject);
var
TabSheet: TTabSheet;
frmTest : TForm;
begin
TabSheet := TTabSheet.Create(PageControl1);
TabSheet.Caption := 'kjklhhj';
TabSheet.PageControl := PageControl1;
frmTest := TForm1.Create(Nil);
frmTest.Show;
frmTest.Parent := TabSheet;
end;
我按照大家所说的做了一切:another Whosebug question
我的问题,新创建的固定到 Tabsheet 的表单如何在不抛出异常的情况下访问它自己的过程?另一件可能很重要的事情:当我有 delphi Auto-Create 表单时,没有访问冲突,但该方法对表单没有任何作用,所以我认为该过程可能会更改错误表单上的内容,一个尚未创建的(提供 AV),而不是我刚刚创建的那个,或者应用程序没有在我的新表单上调用该方法,而是在尚未创建该表单的地方调用一个。
如果我 auto-create 表单,调用过程可能会更改应用程序启动时创建的表单上的标签,而不是新表单..
任何帮助将不胜感激,因为我已经谷歌搜索了几个小时但对这个问题没有真正的帮助
提前致谢:)
如果您打算创建 TForm1
class 的多个实例,那么不 auto-create Form1
是正确的。事实上,您应该完全删除 Form1: TForm1
声明以减少出错的风险。
您可能希望保留对您创建的表单的引用 f.ex。在 TList
中,可能由 TfrmPage
实例托管,具体取决于 TfrmPage
是什么。 (见下文关于 AV 的讨论)
访问冲突
当您在 TfrmPage.CDMAClick()
中创建 TForm1
的实例时,您将创建的表单的引用分配给局部变量 frmTest
,然后将其显示在标签表中。您可以单击 Button1
并更改 Label1
的标题。但是,当您调用 ChangeLabel
过程时,您声明
Form1.Label1.Caption := str;
但是 Form1
变量从未被分配,因此是 nil
并且 AV 被触发。现在,由于您将表单引用分配给 TfrmPage.CDMAClick()
中的本地 frmTest
变量,您实际上不再对表单有任何引用,也无法访问它(实际上,因为您将它作为标签表的父级,您可以在选项卡控件中搜索它)。这就是为什么我建议在列表中保留对您创建的表单的引用。然后您可以在需要时通过该列表访问表单。
My Question, how can the newly created form, pinned to the Tabsheet, access its own procedures without throwing exceptions?
您始终可以从 object 本身访问 object 的方法、字段和属性,而无需使用引用变量。事实上,你永远不应该在 object:
中使用 objects 引用变量 Label1.Caption := 'Whatever'; // correct from within the form
有时可能需要在 object 中使用引用,为此您可以使用 self
f.ex.:
self.Label1.Caption := 'Whatever'; // self can be used if needed
从外部 method/procedure/function 您需要使用对 object
的引用 Form1.Label1.Caption := 'Whatever'; // assuming Form1 has been assigned