开发者

.NET Windows Forms - intercepting the Close X event

开发者 https://www.devze.com 2022-12-29 23:48 出处:网络
This must be a dumb question, but I cannot figure it out. I also cannot use the designer because coders before me managed to throw GUI and logic all in one, so now it is confused. I\'ve got to do it t

This must be a dumb question, but I cannot figure it out. I also cannot use the designer because coders before me managed to throw GUI and logic all in one, so now it is confused. I've got to do it the old school way.

I have a Form which can be closed in 3 ways: Close button, File / Close menu, an开发者_Python百科d the X icon. I want them all to do the same thing. Intercepting the button and the menu events is easy. In fact, both are hooked up to an onCloseConfig method. Btw, is there a better name for this method?

private void onCloseConfig(object sender, System.EventArgs e)
{
    if (! m_configControl.Modified)
    {
        Application.Exit(); // Or should it be this.Close();
    }
    ....
    // Else present a dialog, ask if they want to save.
}

So, to intercept the X I tried: this.FormClosing +=new FormClosingEventHandler(this.onCloseConfig); I believe this is what causes an infinite loop. I do not want that :) FormClosed is another option, but it seems too late. I just want to intercept the fact that the X was clicked, not the fact that the form is closing.


I think you do want form closing, the thing you may be missing is to check the reason for closing and only cancel it if it is from the user e.g.

private void my_FormClosing(object sender, FormClosingEventArgs e)
{
  if (e.CloseReason == CloseReason.UserClosing)
  {
    e.Cancel = true; //I'm sorry Dave, I'm afraid I can't do that.
  }
}

to hide the 'X' set Form.ControlBox = false, but this will get rid of min/max as well.


Create a separate method for the button/menu close:

private void myButton_Click(object sender, EventArgs e)
{
    this.Close();
}

private void myMenuButton_Click(object sender, EventArgs e)
{
    this.Close();
}

private void myForm_FormClosing(object sender, FormClosingEventArgs e)
{
    if (m_configControl.Modified)
    {
        var result = MessageBox.Show("Name Of Application", "Would you like to save before closing?", MessageBoxButtons.YesNoCancel);
        if(result == DialogResult.Yes)
            //Save here
        else if(result == DialogResult.Cancel)
            e.Cancel = true;
    }
}

Or, you can disable the close-button ("X") altogether by setting this.ControlBox = false


Btw, is there a better name for this method?

Close[FormName] could be a better choice.

Or should it be this.Close();

Yes, if all you want is to close the form.

You should create a new event handler for FormClosing event. It takes in FormClosingEventArgs and not EventArgs as a parameter. In the click handlers of the button and menu item, just do a this.Close().

This will call the event and you can place all your checks there.


The FormClosed event occurs once the form is closed. That is definitely not what you want.

The FormClosing event is more likely what you need.

The FormClosing event is triggered whatever button or menu link is clicked. Anything that tries to close the form will trigger the FormClosing event.

Now, the more appropriate way to use the FormClosingEventArgs would be the following within your FormClosing event handler method:

if(m_configControl.Modified)
    e.Cancel = true;

so unless the config control is modified, the form will keep closing. You want to prevent it from closing only if there are changes or unsaved changes.

EDIT 2 After rereading your question, see below my changes to the upper code:

if(m_configControl.Modified)
    if(DialogResult.OK == MessageBox.Show("Do you want to save changes?", "Changes detected")
        SaveChanges();

This will then prompt the user for unsaved changes and save only if the user clicked OK in the MessageBox. Note that you will have to add the buttons accordingly in the additional parameters of the MessageBox.Show() method.

If you want to accomplish an Yes/No/Cancel upon FormClosing, then you will have to go this way:

if(m_configControl.Modified) {
    DialogResult dr = MessageBox.Show(...);
    switch(dr) {
        case DialogResult.OK:
            SaveChanges();
            break;
        case DialogResult.No:
            // Do nothing...
            break;
        case DialogResult.Cancel:
            e.Cancel = true;
    }
}

So, when the user clicks Yes, your application will save the changes. When he clicks No, the application will do nothing about it and will continue its closing. When the user wishes to come back to the application, then Close will be prevented.

EDIT 1 Take an eye out on my answer to This Question which seems quite what you want to accomplish.


This should stop window from closing: FormClosing(object sender, System.EventArts e) { if (e.CloseReason == CloseReason.UserClosing) e.Cancel = true; }

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号