tags:

views:

759

answers:

5

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

+3  A: 
Philip Wallace
+2  A: 

Override OnFormClosing?

RandomNoob
A: 

This is a pretty commonly asked question. One good answer is here:

http://stackoverflow.com/questions/1562808/vb-net-overload-default-functionality-when-user-clicks-the-x-close-program


If you don't feel comfortable putting your code in the Form_Closing event, the only other option I am aware of is a "hack" that I've used once or twice. It should not be necessary to resort to this hack, but here it is:


Don't use the normal close button. Instead, create your form so that it has no ControlBox. You can do this by setting ControlBox = false on the form, in which case, you will still have the normal bar across the top of the form, or you can set the form's FormBorderStyle to "None. If you go this second route, there will be no bar across the top, or any other visible border, so you'll have to simulate those either by drawing on the form, or by artistic use of Panel controls.

Then you can add a standard button and make it look like a close button, and put your clean-up code in there. At the end of the button event, just call this.Close() (C#) or Me.Close() (VB)

David Stratton
Why wouldn't one feel comfortable in handling the Closing event? IMHO adding a custom (but convincing) Close button is not so trivial (especially when you take transition effects and Aero stuff into account, which you normally get without any pain).
Groo
In the answer I linked to, the person whoposed the question didn't want to use the Form_Closing event for some reason. I'm not sure what his reason was, but he didn't want to use it. The times I used the hack, I just wanted a close button with a different look.
David Stratton
+10  A: 

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;
    }        
}
Jon B
My guess is he wants to minimize to tray, but you get the +1 from me for saying be careful.
280Z28
@Jon B - you should check the close reason. If Windows is shutting down, you don't want to be showing message boxes.
Philip Wallace
I made it a switch statement so I don't have to scroll off to the right to read the right hand side of the `==`
280Z28
@Philip - good point.
Jon B
@Philip: well, that depends. A "Do you want to save" box should be shown everytime it is relevant (there are changes) and canceling should cancel shutdown. That's what happens with VS, for example. An annoying "Do you want to close" should be shown... ideally, never, but if you're going that way, that one you should bypass on shutdown.
Martinho Fernandes
@Phillip - is this actually recommended? I believe most applications will ask you if you want to save changes to a modified file, regardless of the close reason.
Groo
Philip Wallace
+4  A: 

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.

Chap