Search code examples
c#winformsowner

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


I got two forms, main and second form. Since I want to navigate between them easily, while avoiding creating multiple instances of each, I used this at main form:

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

and the code below at second form:

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

Everything works just perfect, except the fact that I can't close the application. When I go to second form and back to main, close button won't work anything at all.

How can I close the program while I still use this code?

I also tried this code to see if close button is working itself:

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

MessageBox was shown, but nothing happened after.


Solution

  • This happen because the second Form is not closed - you use e.cancel = true on it. Add the folowing line if you want to force closure of all application windows

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

    then in form2, you can check if close is directed from user or from Application:

    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
    }
    

    Or you can use CloseReason.UserClosing to direct your cancellation depending on parentship. For example:

     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 
        }