编辑正文以获取更多详细信息。
我有一个名为ENP的表单,在EnpView单元中定义。 ENP表单是在主窗体(TPrincipal)中单击工具栏项的处理程序事件中创建和显示的。
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(self).Show();
end;
Enp表单知道(在公开声明中)clearGrid()消息。
ENP Form有一个名为StringGrid的TStringGrid。还有一个名为“添加”的按钮。单击“添加”按钮时,将创建另一个表单并显示:AddEnp表单,在EnpViewAdd单元中定义。
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(self).Show();
end;
AddEnp表单,有任何TEdits。输入的值必须在EnpView.StringGrid中添加。
我试试这个:
implementation
uses
EnpView, Main;
procedure TAddEnp.AgregarClick(Sender: TObject);
begin
{ Agrego el nodo xml }
Globals.Xml.agregarMuestra(muestra.Text);
Globals.Xml.insertEnp(muestra.Text,golpes.Text,metros.Text);
{ Send messages to EnpView Form }
ENP.clearGrid();
ENP.populateGrid();
end;
第1行中的ClearGrid消息失败,存在访问冲突:
procedure TENP.clearGrid();
begin
Self.StringGrid.RowCount := 2;
Self.StringGrid.Rows[1].Clear();
end;
如果在类中发送,则clearGrid方法有效。有什么想法?。
答案 0 :(得分:1)
在TAddENP中创建一个名为ENPForm的属性,并在创建后立即分配ENP表单。声明如下:
TAddENP = class(TForm)
private
FENPForm: TENP;
// all of your already existing declarations
public
property ENPForm: TENP read FENPForm write FENPForm;
end;
现在您可以参考ENP表格,您可以随意使用它。
在创建TAddENP表单期间,请执行以下操作:
procedure TENP.opAgregarClick(Sender: TObject);
var
addForm: TAddENP;
begin
addForm := TAddEnp.Create(Self);
addForm.EnpForm := Self;
addForm.Show;
end;
现在您创建了第二个表单,并为第一个表单提供了安全引用。他们现在可以安全地互相交谈。
我建议你避免让一个表单操作其他组件,因为这会增加它们之间的依赖关系。相反,声明公共方法来做到这一点,因此表单将取决于它们的接口,而不是它们的实现。
我希望这会有所帮助。
答案 1 :(得分:0)
从您的问题(我添加code-style
以使其更清晰):
我有一个名为
ENP
的表单,在EnpView
单元中定义。ENP
表单, 从单击工具栏项的处理程序事件创建并显示 在主要表格(TPrincipal
)。
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(self).Show();
end;
这与您的ENP
表单变量无关
您创建TENP
表单类的实例并使用Show
显示该实例,但未分配ENP
变量。
您无法将实例分配给ENP
变量,因为每次单击按钮都会创建一个新实例(因此您有多个TENP
实例)。
然后,您创建了TAddEnp
实例和(从未声明的ENP
变量)的复杂依赖。
您可以通过创建TAddEnp
实例来实现此目的(为什么TAddEnp
在此而不是TAddENP
?)使用Show
显示它(让用户有机会返回{ {1}}实例,然后再次点击TENP
按钮创建更多opAgregar
的实例:
TAddEnp
然后让procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(self).Show();
end;
依赖于TAddEnp
变量:
ENP
这确实会失败:
第1行中的ClearGrid消息失败,存在访问冲突:
procedure TAddEnp.AgregarClick(Sender: TObject);
begin
//...
ENP.clearGrid();
ENP.populateGrid();
end;
原因是procedure TENP.clearGrid();
begin
Self.StringGrid.RowCount := 2;
Self.StringGrid.Rows[1].Clear();
end;
未分配(默认情况下为ENP
),因此在nil
内,clearGrid
也将Self
您可以实施的解决方案
nil
和TENP
的单个实例,使用TAddEnp
强制模式以防止用户多次点击相同的按钮。ShowModal
行为,但将每个Show
实例绑定到从中创建的TAddEnp
实例。对于第一个解决方案,您的代码将变为:
TENP
和
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
ENP := TENP.Create(Application);
ENP.ShowModal();
ENP.Release();
ENP := nil;
end;
第二个将需要更多努力,因为您需要阻止使用现有变量。
procedure TENP.opAgregarClick(Sender: TObject);
begin
AddEnp := TAddEnp.Create(Application);
AddEnp.ShowModal();
AddEnp.Release();
AddEnp := nil;
end;
变量。ENP
变量。修复AddENP
- >方法中的self
Self
和
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(Self).Show();
end;
这里添加依赖项:
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(Self).Show();
end;