1

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

4

2 回答 2

3

您没有阻止它关闭,您忘记将 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,目前尚不清楚。

于 2014-10-26T11:33:49.150 回答
1

你真的不需要在这里覆盖任何东西。只需处理FormClosing事件并设置e.Cancel = True. 另外,让您的表单在同一个处理程序中不可见。在第一个表单中,创建第二个表单的类级别对象,并ShowDialog()在“搜索”按钮的单击时调用它。最后确保您的OKCancel按钮的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();
    }
}
于 2014-10-26T10:48:34.947 回答