现在我有2个表格。在Form1上我打开Form2,如下所示:
procedure TForm1.Action1Execute(Sender: TObject);
var
Form2: TForm2;
begin
Form2 := TForm2.Create(Form2);
Form2.ShowModal;
Form2.Free;
end;
现在我想用一个按钮关闭Form2。所以我试过
procedure TForm2.cancelBtnClick(Sender: TObject);
begin
Form2.Close;
end;`
但是,当我点击该按钮时,这只会给我访问冲突错误。我做错了什么?
答案 0 :(得分:17)
执行此操作的常规方法是执行
procedure TForm1.Action1Execute(Sender: TObject);
begin
with TForm2.Create(nil) do
try
ShowModal;
finally
Free;
end;
end;
并且,如果TForm2
包含“确定”按钮,则应在设计时将ModalResult
属性设置为mrOK
。使用对象检查器进行设置。您可能还想将Default
设置为True
。现在,您可以通过按键盘上的Enter键“点击”确定按钮!
此外,如果对话框中有“取消”按钮,则应将ModalResult
设置为mrCancel
,将Cancel
设置为True
。现在,您可以通过按键盘上的Escape键“点击”取消按钮!
值为ModalResult
的按钮将自动关闭模式对话框。
答案 1 :(得分:6)
由于表单以模态方式显示,因此正确的解决方案是在按钮单击处理程序中设置ModalResult := mrCancel
。快捷方式是将按钮的ModalResult
属性设置为mrCancel
,然后您甚至不需要事件处理程序。
请注意,您的表单创建不正确。您将未分配的变量Form2
作为Owner
参数传递给构造函数。我希望这是访问冲突的原因。
您应该传递另一个表单,例如Application
或nil
。实际上在这种情况下你也可以传递nil,以便代码应该是:
Form2 := TForm2.Create(nil);
try
Form2.ShowModal;
finally
Form2.Free;
end;
如果您通过了所有者,那么当所有者被销毁时,该表单将被销毁。由于您自己正在销毁它,因此您无需通过所有者。
也就是说,设置所有者有时很有用,例如,如果您使用Postion
属性值之一根据所有者的位置设置表单的位置。如果是,那么我建议在此实例中传递Self
,这是TForm1
对象引用。
答案 2 :(得分:2)
另外两个答案讨论了解决问题的其他方法。
我将指出问题的原因。
您有两个名为Form2的变量。一个包含表单,另一个未初始化,很可能是Nil。 A / V的原因是因为您访问了Nil变量。
在类中使用时,应该避免使用类的变量名,而是可以直接引用它的成员,例如在不引用变量的情况下调用Close;
。为了清楚起见,您还可以在self.
前加上前缀,因此请将form2.close;
替换为self.close;
答案 3 :(得分:1)
在你的第二个代码中,你已经在表单2中了,所以你只需要做
procedure TForm2.cancelBtnClick(Sender: TObject);
begin
Close;
end;
如果你在第一个代码中创建了一个变量,你没有使用在表单中作为公共变量的泛型Form2变量,那么它就不会分配给你调用的表单。所以它会给出错误。如果在单元的顶部,您删除了“var Form2:TForm2;”你会看到它抱怨该行缺少变量,将其更改为关闭,它会消失,你的错误也会消失。
答案 4 :(得分:1)
我不知道你是否已经解决了这个问题或创建了一个新的代码来避免这个问题,但我认为正在发生的事情(你没有展示所有代码来确认)是你创建了错误的代码OnActivate主表单事件。
当您退出第二个表单时,您将返回到主表单并再次“激活”。 可能你操纵了一个不存在的物体。