Annoying Bot
Annoying Bot

Reputation: 359

Canceling closing of C# Form

My program has two ways to close, one being the 'X' in the top-right corner and the other being an 'Exit' button. Now, when either one of these is pressed when a certain condition is met, a message pops up notifying the user that they haven't saved yet. If they DID save, the message won't pop up and the program closes as normal. Now, when the message DOES pop up, the user gets a MessageBox with Yes and No buttons. If 'Yes' is pressed, the program needs to save. If 'No' is pressed, the program needs to cancel the close event that has been initiated when the user pressed the 'X' or 'Exit' button.

What is the best way to do this?

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    TryClose();
}

private void TryClose()
{
    if (saved == false)
    {
        //You forgot to save
        //Turn back to program and cancel closing event
    }
}

Upvotes: 2

Views: 1560

Answers (7)

Adam Plocher
Adam Plocher

Reputation: 14243

This will do what you need:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = !TryClose();
}

private bool TryClose()
{
    return DialogResult.Yes == MessageBox.Show("Are you sure?", "Are you sure?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
}

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564851

FormClosingEventArgs includes a Cancel property. Just set e.Cancel = true; to prevent the form from closing.

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (!saved)
        e.Cancel = true;
}

Edit in response to comments:

Since your goal is to allow the same "save method" to be used, I would change it to return bool on success:

private bool SaveData()
{
     // return true if data is saved...
}

Then you can write:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // Cancel if we can't save
    e.Cancel = !this.SaveData();
}

And your button handlers, etc, can all still call SaveData() as needed.

Upvotes: 4

Tim
Tim

Reputation: 887

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = !TryClose();
    }

    private bool TryClose()
    {
        if (!saved)
        {
            if (usersaidyes)
            {
                // save stuff
                return true;
            }
            else if (usersaidno)
            {
                // exit without saving
                return false;
            }
            else
            {
                // user cancelled closing
                return true;
            }
        }
        return true;
    }

Upvotes: 0

BlueMonkMN
BlueMonkMN

Reputation: 25601

Override OnFormClosing:

 protected override void OnFormClosing(FormClosingEventArgs e)
 {
    if (saved == true)
    {
       Environment.Exit(0);
    }
    else /* consider checking CloseReason: if (e.CloseReason != CloseReason.ApplicationExitCall) */
    {
       //You forgot to save
       e.Cancel = true;
    }
    base.OnFormClosing(e);
 }

Upvotes: 0

Amit
Amit

Reputation: 321

You can call Close from the exit button. and then Handle closing in the Forms.FormClosing event as others have said. This will handle both Exit Button Click and Forms Closing from "X"

Upvotes: 0

JaredPar
JaredPar

Reputation: 755457

To cancel the closing event just set the Cancel property to true on the FormClosingEventArgs instance

if (!saved) {
  // Message box
  e.Cancel = true;
}

Upvotes: 0

Grant Thomas
Grant Thomas

Reputation: 45068

Use the Cancel property of the event args, set it to true to cancel.

Upvotes: 0

Related Questions