对主表单使用 Owner.Show() 时,应用程序保持打开状态

Application remain open when using Owner.Show() for main Form

我有两种形式,主要形式和第二种形式。因为我想在它们之间轻松导航,同时避免为每个实例创建多个实例,所以我在 main form:

中使用了它
Form2 secondForm = new Form2();
private void btnForm2_Click(object sender, EventArgs e)
{
 secondForm.Show(this);
 Hide();
}

和下面的代码 second form:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{ 
 e.cancel = true;
 Owner.Show();
 Hide();
}

除了我无法关闭应用程序之外,一切都很完美。当我转到第二个表单并返回主表单时,关闭按钮根本不起作用。

如何在我仍然使用此代码时关闭程序?

我也试过这段代码来查看关闭按钮是否正常工作:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {
      MessageBox.Show("Closing");
 } 

显示了 MessageBox,但之后没有任何反应。

使用

Environment.Exit(0);

关闭

正在关闭 Form1 'tries' 以关闭 form2。运行取消关闭并运行 form1 的 Form2_Closing 事件。

取消订阅事件的代码(快速且肮脏),注意 Form2 上的内部修饰符。您可以考虑将 stop/start 订阅作为方法。

    private void btnForm2_Click(object sender, EventArgs e)
    {

        secondForm.FormClosing += secondForm.Form2_FormClosing;
        secondForm.Show(this);
        Hide();
    }

    internal void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;



        FormClosing -= Form2_FormClosing;
        Owner.Show();
        Hide();
    }

发布这篇文章后,我意识到您可以使用 FormClosingEventArgs.CloseReason 属性 来获得更简单的解决方案:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.FormOwnerClosing) { return; }
        e.Cancel = true;
        Owner.Show();
        Hide();


    }

发生这种情况是因为第二个表单未关闭 - 您在其上使用 e.cancel = true。如果要强制关闭所有应用程序,请添加以下行 windows

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {
     System.Windows.Forms.Application.Exit();
 } 

然后在 form2 中,您可以检查关闭是来自用户还是来自应用程序:

void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
 //close button click by user on form 2
    if(e.CloseReason == CloseReason.UserClosing)
        e.cancel = true //cancel event
   else
     e.cancel = false //close this form
}

或者您可以使用 CloseReason.UserClosing 来根据父母身份直接取消。例如:

 void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {

//check if closing signal is from parent
       if   (e.CloseReason == CloseReason.UserClosing.FormOwnerClosing)
         e.cancel = false //close this form
      else 
          e.cancel = true 
    }

我更喜欢简单的解决方案。

在Form1_FormClosing中使用:

secondForm.Close();

这是妙语。在 Form2_FormClosing 中包装您已有的代码:

if (this.Visible)
{
    ...
}

这对我有用。当我关闭主窗体时,它会关闭,因为 Form2 不可见并且知道不取消关闭。

由于答案指定 Environment.Exit(0);得到了支持,请参阅 winforms - How to properly exit a C# application? - Stack Overflow. It quotes the MSDN saying it is for console applications. I don't see that in the current documentation but it appears to still be relevant. Also see Application.Exit() vs Application.ExitThread() vs Environment.Exit()。协议好像是Environment.Exit,Application.ExitTread和Application.Exit,Application.Exit好像最好。然而,我不会使用它们中的任何一个,除非异常终止我的应用程序,例如在错误中。