Rohit Raghuvansi
Rohit Raghuvansi

Reputation: 2864

why form_closing() is firing twice?

I am working on a windows form application. I want to show user a message stating close reason when user clicks "X" button in the main window.With "X" button i mean "close" button in "minimize","maximize" and "close" tray in windows.

I have written this code.

 private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (MessageBox.Show("This application is closing down because of " + e.CloseReason.ToString() + ". Do you really want to close it ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
        {                
            e.Cancel = true;
        }
        else
        {
            Application.Exit();
        }
    }

Now what happens is,If user clicks no to message box,event is discarded and when user clicks yes,form_closing() fires again and shows other messagebox.So messagebox is shown twice.I want to show it once.Please help and tell why is it firing twice.

Upvotes: 1

Views: 3260

Answers (10)

Eric Twose
Eric Twose

Reputation: 173

Application.Exit() calls frmX_FormClosing().

That's why FormClosing() gets called twice.

Upvotes: 0

Charlston Mabini Vita
Charlston Mabini Vita

Reputation: 174

try this: this will be a great help

   private void Master_FormClosing(object sender, FormClosingEventArgs e)
    {
        DialogResult result = MessageBox.Show("Do you really want to exit the program?", "Data Patch", MessageBoxButtons.YesNo);

        if (result != DialogResult.Yes)
        {
            e.Cancel = true;
        }
    }

Upvotes: 0

92AlanC
92AlanC

Reputation: 1387

I've just had that same problem. This is what I did to get around it:

private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (MessageBox.Show("This application is closing down because of " + e.CloseReason.ToString() + ". Do you really want to close it ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
        {
            e.Cancel = true;
        }
        else
        {
            try
            {
                Environment.Exit(0); // It will try to close your program "the hard way"
            }
            catch (Exception)
            {
                Application.Exit(); // If a Win32 exception occurs, then it will be able to close your program "the normal way"
            }
        }
    }

I'm sure it's going to work for you, if you haven't already found a solution or even given up on that code as it's been quite a while.

Upvotes: -1

Vic85
Vic85

Reputation: 63

I think @Tornado726 already answered the best possible answer for all. But there is just one Copy/Paste mistake I guess (typed form_closing twice)

Private Sub FORM1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing

    Select Case (MessageBox.Show("Do you really want to close?", "Quit", MessageBoxButtons.YesNo))
        Case MsgBoxResult.No
            e.Cancel = True
    End Select
End Sub

Private Sub FORM1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
    Application.Exit()
End Sub

Upvotes: 0

Tornado726
Tornado726

Reputation: 350

I had this same issue and determined that the Application.Exit() was calling the FormClosing event. Only put Application.Exit() in the FormClosed event, instead of the FormClosing event.

Use this code:

private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
{
    if (closingPending) return;
    if (MessageBox.Show("This application is closing down because of " + 
e.CloseReason.ToString    () + ". Do you really want to close it ?", ""
, MessageBoxButtons.YesNo) == DialogResult.No)
{                
    e.Cancel = true;
}
else
{
    closingPending = true;
    // Application.Exit(); <-- Remove this

}

private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
{
    Application.Exit();    <-- Put it here.
}

Upvotes: 0

Karthic Raghupathi
Karthic Raghupathi

Reputation: 2061

I know this is old and I stumbled upon this question as I encountered the same behavior. I'm using .Net 4.5 and here is how I went about this issue:

private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        if (MessageBox.Show("This application is closing down because of " + e.CloseReason.ToString() + ". Do you really want to close it ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
        {                
            e.Cancel = true;
        }
        else
        {
            Application.Exit();
        }
    }   
}

You can find more information about CloseReason enumeration here: http://msdn.microsoft.com/en-us/library/system.windows.forms.closereason.aspx

Upvotes: 1

Abhishek Shrestha
Abhishek Shrestha

Reputation: 121

Private Sub ClaimEditor_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    If MsgBox("Edit mode active. Exit without saving?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "Edit mode") <> MsgBoxResult.Yes Then
        e.Cancel = True
        Exit Sub
        'Else
        '    e.Cancel = False
    End If
    WriteIntoRregistry()
    RemoveHandler Me.FormClosing, AddressOf ClaimEditor_FormClosing
    Application.Exit()
End Sub

Upvotes: 0

Mario
Mario

Reputation: 21

I know this thread is a bit old, but why not:

    $Application.OpenForms["NameOfMainForm"].Close;

Upvotes: 2

Przemaas
Przemaas

Reputation: 851

You can skip the else part of your application. If your form is main form of application, it will exit anyway. Application.Exit() causes all windows to close. Your "first" close is still pending, so form is not yet closed and Application.Exit() tries to close your form for the second time.

You can try this:

bool closingPending = false;
private void frmIMS_FormClosing(object sender, FormClosingEventArgs e)
{
    if (closingPending) return;
    if (MessageBox.Show("This application is closing down because of " + e.CloseReason.ToString() + ". Do you really want to close it ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
    {                
        e.Cancel = true;
    }
    else
    {
        closingPending = true;
        Application.Exit();
    }
}

Upvotes: 2

Scoregraphic
Scoregraphic

Reputation: 7200

Why Application.Exit in the else branch? This is done automatically and may solve your problem.

Upvotes: 0

Related Questions