如何在C#中正确覆盖OnFormClosing()方法

时间:2014-10-26 10:25:44

标签: c# formclosing

我的表单中有一个名为" Search"的按钮。当我单击它时,会打开另一个表单来搜索项目。当用户点击第二个表单中的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.

2 个答案:

答案 0 :(得分:2)

您没有停止关闭,您忘记将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,但它并不清楚。

答案 1 :(得分:1)

你真的不需要在这里覆盖任何东西。只需处理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();
    }
}