【问题标题】:Application remain open when using Owner.Show() for main Form将 Owner.Show() 用于主窗体时,应用程序保持打开状态
【发布时间】:2016-08-18 20:03:16
【问题描述】:

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

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

下面的代码第二种形式

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 显示出来了,但之后什么也没发生。

【问题讨论】:

    标签: c# winforms owner


    【解决方案1】:

    使用

    Environment.Exit(0);
    

    关闭

    【讨论】:

    • 看起来Application.ExitTread(); 也有效。但是这些关闭程序的安全方法吗?
    • Environment.Exit(0); 是关闭应用程序的方式,this.Close() 仅关闭该实例,但 Environment.Exit(0); 关闭整个应用程序
    • 查看我的答案以获得解释。
    【解决方案2】:

    发生这种情况是因为第二个表单没有关闭 - 你使用 e.cancel = true 就可以了。如果要强制关闭所有应用程序窗口,请添加以下行

    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 
        }
    

    【讨论】:

    • 这个工作原理与按下关闭按钮完全一样,但不起作用。
    • 你说得对,Enviroment.Exit(0) 强制关闭。我会更正我的答案
    【解决方案3】:

    关闭 Form1 '尝试'关闭 form2。运行您的 Form2_Closing 事件,该事件取消关闭并运行 form1。

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

        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();
    
    
        }
    

    【讨论】:

    • 有没有办法在 Form1_Closing 事件中更改 Form2_Closing 事件?
    • 您可以在显示时订阅该事件,并在 Form2 关闭时取消订阅该事件。
    • 好像是我要找的答案,能不能写个代码例子?
    • 您的建议效果很好。你写的这段代码正是我想要的答案:if (e.CloseReason != CloseReason.FormOwnerClosing) { e.Cancel = true; Owner.Show(); Hide(); }你能编辑答案,让它在顶部吗?
    【解决方案4】:

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

    在Form1_FormClosing中使用:

    secondForm.Close();
    

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

    if (this.Visible)
    {
        ...
    }
    

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

    由于答案指定 Environment.Exit(0);获得了投票,请参阅winforms - How to properly exit a C# application? - Stack Overflow。它引用 MSDN 说它是用于控制台应用程序的。我在当前文档中没有看到这一点,但它似乎仍然相关。另见Application.Exit() vs Application.ExitThread() vs Environment.Exit()。该协议似乎是Environment.Exit,Application.ExitTread和Application.Exit,Application.Exit似乎是最好的。但是,我不会使用它们中的任何一个,除非异常终止我的应用程序,例如出现错误。

    【讨论】:

    • 人们应该解释反对票。我对否决票的唯一解释是它解释了 Environment.Exit(0) 用于控制台应用程序。如果问题是对另一个答案的引用,那么我可以删除“由于答案指定”部分;解释这比匿名投票要好。
    • 我也不明白反对票。我也担心Invironment.Exit(0),它可以工作,但这不是关闭应用程序的正常方式。
    • 你还喜欢使用 CloseReason.UserClosing 的答案吗?我不明白这个问题。
    • 两种方式都很好,唯一的区别可能是其他方式可以用于更多不同的情况。
    • 我想这是个人喜好问题。我个人尽可能避免 Application.Exit 之类的事情,我更喜欢尽可能控制发生的事情。对于这样简单的事情,这并不重要,但当事情变得复杂时,简单的解决方案往往会成为大问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    相关资源
    最近更新 更多