Override standard close (X) button in a Windows Form

How do I go about changing what happens when a user clicks the close (red X) button in a Windows Forms application (in C#)?


You can override OnFormClosing to do this. Just be careful you don't do anything too unexpected, as clicking the 'X' to close is a well understood behavior.

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    if (e.CloseReason == CloseReason.WindowsShutDown) return;

    // Confirm user wants to close
    switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing", MessageBoxButtons.YesNo))
    {
    case DialogResult.No:
        e.Cancel = true;
        break;
    default:
        break;
    }        
}

Override the OnFormClosing method.

CAUTION: You need to check the CloseReason and only alter the behaviour if it is UserClosing. You should not put anything in here that would stall the Windows shutdown routine.

Application Shutdown Changes in Windows Vista

This is from the Windows 7 logo program requirements.


One thing these answers lack, and which newbies are probably looking for, is that while it's nice to have an event:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // do something
}

It's not going to do anything at all unless you register the event. Put this in the class constructor:

this.FormClosing += Form1_FormClosing;

Either override the OnFormClosing or register for the event FormClosing.

This is an example of overriding the OnFormClosing function in the derived form:

protected override void OnFormClosing(FormClosingEventArgs e)
{
   e.Cancel = true;
}

This is an example of the handler of the event to stop the form from closing which can be in any class:

private void FormClosing(object sender,FormClosingEventArgs e)
{  
   e.Cancel = true;
}

To get more advanced, check the CloseReason property on the FormClosingEventArgs to ensure the appropriate action is performed. You might want to only do the alternative action if the user tries to close the form.


as Jon B said, but you'll also want to check for the ApplicationExitCall and TaskManagerClosing CloseReason:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (  e.CloseReason == CloseReason.WindowsShutDown 
        ||e.CloseReason == CloseReason.ApplicationExitCall
        ||e.CloseReason == CloseReason.TaskManagerClosing) { 
       return; 
    }
    e.Cancel = true;
    //assuming you want the close-button to only hide the form, 
    //and are overriding the form's OnFormClosing method:
    this.Hide();
}