Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fire FormClosing for ownerless forms on red X exit?

Tags:

c#

winforms

I have a small app with several forms, each of which saves their pane layout during the FormClosing event.

Some forms need to remain on screen when the main form is minimized, so they're opened ownerless with form.Show(), as opposed to form.Show(this).

However this affects FormClosing behaviour - when the user exits using the red X, the FormClosing event doesn't get fired for the ownerless forms.

Application.Exit() does work as needed, but cancelling the FormClosing event in the main form and calling Application.Exit() instead causes FormClosing to be called twice on everything other than the ownerless forms.

I could probably iterate OpenForms in the FormClosing event of the main form and save anything that needs saving, but that seems a bit of a hack. Is there a way to make X behave in the same way as Application.Exit()?

The following code demonstrates the problem:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.Text = "Main";

        Form ownedForm = new Form { Text = "Owned" };
        ownedForm.FormClosing += (s, e) => { System.Diagnostics.Debug.WriteLine("FormClosing owned form"); };
        ownedForm.Show(this);

        Form ownerlessForm = new Form { Text = "Ownerless" };
        ownerlessForm.FormClosing += (s, e) => { System.Diagnostics.Debug.WriteLine("FormClosing ownerless form"); };
        ownerlessForm.Show();

        this.FormClosing += (s, e) =>
        {
            System.Diagnostics.Debug.WriteLine("FormClosing main form");

            // fix below doesn't work as needed!
            //if (e.CloseReason == CloseReason.UserClosing)
            //{
            //    e.Cancel = true;
            //    Application.Exit();
            //}
        };
    }
}
like image 879
jlmt Avatar asked Oct 04 '13 17:10

jlmt


1 Answers

Add an event handler to the main form's FormClosing handler to close the ownerless forms when the main form is closed:

ownerlessForm.Show(); //right after this line that you already have
FormClosing += (s, e) => ownerlessForm.Close(); //add this

This will ensure that they are closed gracefully, and will have their closing events run, rather than having the main thread end and have the process be torn down without letting these forms gracefully close.

like image 129
Servy Avatar answered Nov 08 '22 03:11

Servy