c# - 为什么在模态对话框中调用 Hide() 时 FormClosing 会触发两次?

标签 c# .net winforms formclosing

我们创建了一个通过 ShowDialog 显示的新表单,并向其添加了一个“取消”按钮。以下是我们如何从其父级打开表单:

// _modalForm is a class-level instance of our ModalForm class
var result = _modalForm.ShowDialog(this);
MessageBox.Show(result.ToString());

这是 ModalForm 中取消按钮的 Click 事件处理程序。

private void btnCancel_Click(object sender, EventArgs e)
{
    Close();
}

在我们的 FormClosing 事件中,我们有这段代码(基于 this answer )。

private void ModalForm_FormClosing(object sender, FormClosingEventArgs e)
{
        e.Cancel = true;
        Hide();
        _parentForm.RefreshData();
}

令人惊讶的是,当我们单击“取消”按钮(或使用表单顶部的“X”按钮)时,FormClosing 事件被引发了两次。两次 CloseReason 都是 UserClosing

我仔细检查以确保 InitializeComponent 没有被调用两次并且我们只订阅了一次事件。 btnCancel 未在表单的 CancelButton 属性中设置。它也没有在设计器中设置 DialogResult。但是,当我检查 ShowDialog 的返回值时,它被设置为 DialogResult.Cancel

btnCancel_Click 更改为 DialogResult = DialogResult.Cancel 而不是 Close() 除了 _parentForm.Refresh( )FormClosing 事件中解决了事件被触发两次的问题。

有谁知道为什么在这种特定情况下 FormClosing 事件会引发两次?

最佳答案

那是因为隐藏模态窗体会导致它以 DialogResult.Cancel 作为对话框结果关闭。因此,如果您在 FormClosing 事件中调用 this.Hide(),该事件将再次引发。

想象一下,如果它没有关闭表单,您的应用程序就会被隐藏的模态表单阻止!

注意:答案描述了引发两次事件的原因。但如所述here和其他人提到的,对于模态表单(您使用 ShowDialog 显示),将不会调用 Dispose 方法并且表单在关闭后存在,您可以使用它的属性获取一些数据,或者您可以再次显示它。所以你不需要调用 hide 方法。

有关更多信息,请查看:Do I need to Dispose a Form after the Form got Closed?

关于c# - 为什么在模态对话框中调用 Hide() 时 FormClosing 会触发两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42276233/

相关文章:

c# - 如何在 nhibernate 中急切地加载子集合

c# - .NET 如何创建和执行它的窗口、按钮等?

c# - ASP.NET Core 货币格式无法正常工作

c# - C# 中的小键盘键代码

c# - 计算一整天 c#

c# - 是否有必要取消订阅事件?

c# - 如何 Hook MFC CWnd 创建

.net - 如何获取新建IE8窗口的进程?

vb.net - 使用 VB.NET 获取字符串的第一个字符

c# - 如何在 C# 和 SQL Server 中实现自动完成?值得吗?