Jonathan Tapnio
Jonathan Tapnio

Reputation: 3

FormClosing event fires twice after using exit button

I have a button for exiting the form and this is the code

    DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
    if (dialogResult == DialogResult.No)
    {
    }
    else
    {
        Application.Exit();
    }

I tried using debugger mode, and after I click yes, it goes through Application.Exit() and then fires up the FormClosing event then running the same dialog.

I also tried deleting the code in FormClosing event so it only has Application.Exit() but using Alt+F4 or clicking the X button will exit the application automatically.

My question is how can I question the user if he wants to exit the program but not firing the dialog twice?

Thanks in advance, and I'm letting you all know I'm just a beginner and this is my biggest project so I want to make this great.

Upvotes: 0

Views: 1960

Answers (2)

stuartd
stuartd

Reputation: 73253

Here's an example. It only asks for confirmation if the close was initiated by the user - you probably don't want a MessageBox popping up when Windows is restarting.

private void form_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.Yes)
        {
            Application.Exit();
        }
    }
    else 
    {
        // Cancel the close
        e.Cancel = true;
    }
 }

Upvotes: 3

Amit
Amit

Reputation: 1857

There are two ways to achieve this.

  • By unsubscribe the even on button click
  • As suggested in stuartd's answer, checking reason of closing (but there is a problem in his answer so adding this approach too with fix, so it will help future people.)

I am assuming, As you need this confirmation in both cases, button click and 'x' button click, you have put the same code in both handler.

Approach one

In the handler of button click, while you are asking for user confirmation and if user is clicking 'yes'. Before the line,

Application.Exit();

you should unsubscribe the Form closing event. By doing this, It must not raise form closing event while performing Application.Exit()

assuming your form is MainForm and event is MainForm_Closing, it would look like,

    private void btnClose_Click(object sender, EventArgs e)
    {
        DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
        if (dialogResult == DialogResult.Yes)
        {
            this.FormClosing -= MainForm_FormClosing;
            Application.Exit();
        }
    }

so it will not raise form closing event while performing Application.Exit() and thus your problem will be solved.

Approach Two

As stuartd has suggested (which is more cleaner way according to me. +1 for that), you can check for form closing reason in Form Closing event handler.

Note that there is a little problem (bug) in his sample code [which you have already accepted as an answer!!]. After clicking 'x' button or Alt+F4 by mistake; if user clicks on 'No' on the confirmation message, then too form is being closed because there is no handling for else condition. Proper solution should be like below.

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                DialogResult dialogResult = MessageBox.Show("Are you sure you want to exit?", "Exit Program?", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                    Application.Exit();
                else
                    e.Cancel = true;    //stopping Form Close perocess.
            }
        }

Upvotes: 2

Related Questions