如何在C#中正确重写OnFormClosing()方法
本文关键字:OnFormClosing 重写 方法 | 更新日期: 2023-09-27 18:27:55
我有一个表单,它有一个名为"搜索"的按钮。当我单击它时,会打开另一个表单来搜索项目。当用户点击第二个表单中的X来关闭它时,我并不真的希望它关闭,我只想让它不可见(通过secondForm.visible = false
)。
我发现我需要的只是重写OnFormClosing()
方法,我已经在表单类中完成了这些操作,但它根本没有执行。我知道它没有被执行,因为下次单击"搜索"按钮时(不是执行new SecondForm()
,而是尝试执行secondForm.visible = true
),我会得到一个异常,它说我不能处理已删除的对象(secondForm
)或类似的东西。因此,第二个表单已经关闭,而不是不可见。
在这一点上,我开始认为我需要的是通过某种方式(我显然不知道),将这种新的覆盖方法分配给按钮X。
编辑:
这是我在类的第二个中高估的方法:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (e.CloseReason == CloseReason.WindowsShutDown) return;
this.Visible = false;
}
当点击"搜索"按钮时,我会这样做:
private void btnSearch_Click(object sender, EventArgs e)
{
if (subFormCreated)
subFormSearch.Visible = true;
else
initializeSubFormSearch();
}
private void initializeSubFormSearch()
{
subFormSearch = new SubForm(listaPersonas, actualMostrado);
subFormSearch.Show();
subFormCreated = true;
}
最后,我得到的例外是ObjectDisposedException
。确切的消息类似于(我不知道我是否正确地转换了它)ObjectDisposedException was unhandled. Cannot get access to the deleted object. Name of the object: SubForm.
您没有阻止它关闭,忘记将e.Cancel属性设置为true。正确的代码是:
protected override void OnFormClosing(FormClosingEventArgs e) {
if (e.CloseReason != CloseReason.WindowsShutDown) {
this.Visible = false;
e.Cancel = true;
}
base.OnFormClosing(e);
}
有了额外的细节,永远不想避免调用base。OnFormClosing(),当操作系统关闭时,您在自定义之后调用它,以便客户端程序可以在需要时否决您的决定。
通过订阅主类中的FormClosed事件,使其更有弹性,以便知道需要将subFormCreated变量设置为false。请注意,您不需要该变量,只需将subFormSearch变量设置回null即可。所以,大致来说:
private void displaySubFormSearch() {
if (subFormSearch != null) {
subFormSearch.WindowState = WindowState.Normal;
}
else {
subFormSearch = new SubForm(listaPersonas, actualMostrado);
subFormSearch.FormClosed += delegate { subFormSearch = null; };
}
subFormSearch.Show();
}
通过额外的细节,您可以确保在用户之前最小化窗口的情况下恢复窗口。现在它是坚实的。您可能需要属性来传递更新的listaPersonas和actualMostrado,这还不清楚。
您真的不需要覆盖这里的任何内容。只需处理FormClosing
事件并设置e.Cancel = True
即可。另外,使表单在同一处理程序中不可见。在第一个表单中,创建第二个表单的类级对象,并在单击"搜索"按钮时调用其ShowDialog()
。最后,确保您的确定和取消按钮的DailogResult
属性设置正确。大致看起来是这样的:
class Form1
{
private Form2 dlg;
private void btnSearch_Click(object sender, EventArgs e)
{
if(dlg==null) dlg = new Form2();
dlg.ShowDialog(this);
}
}
class Form2
{
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
this.Hide();
}
}