简体   繁体   中英

How to override correctly OnFormClosing() method in C#

I have a form which has a button called "Search". When I click it, another form is opened to search an item. When the user clicks on the X in this second form to close it, I don't really want it closed, I just want to make it no visible (by secondForm.visible = false ).

I've found that what I need is just to override the OnFormClosing() method and I've done in the form class but it isn't executed at all. I know that it isn't executed because when the next time that "Search" button is clicked (instead of do new SecondForm() it tries just to do secondForm.visible = true ) I get an exception which says that I can't work on an deleted object ( secondForm ) or something like that. So the second form has just been closed instead of no visible.

At this point I'm starting to think that which I need is to assign, by some way (which I obviusly don't know), this new override method to the button X.

EDIT:

This is my overrided method in the second from class:

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

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

        this.Visible = false;
    }

This is what I do when button "Search" is clicked:

private void btnSearch_Click(object sender, EventArgs e)
    {
        if (subFormCreated)
            subFormSearch.Visible = true;
        else
            initializeSubFormSearch();
    }

    private void initializeSubFormSearch() 
    {
        subFormSearch = new SubForm(listaPersonas, actualMostrado);
        subFormSearch.Show();
        subFormCreated = true;
    }

Finally, the exception what I get is ObjectDisposedException . The exact message is something like (I don't know if I'm traslating it correctly) ObjectDisposedException was unhandled. Cannot get access to the deleted object. Name of the object: SubForm. ObjectDisposedException was unhandled. Cannot get access to the deleted object. Name of the object: SubForm.

You didn't stop it from closing, you forgot to set the e.Cancel property to true . Correct code is:

protected override void OnFormClosing(FormClosingEventArgs e) {
    if (e.CloseReason != CloseReason.WindowsShutDown) {
        this.Visible = false;
        e.Cancel = true;
    }
    base.OnFormClosing(e);
}

With the additional details that you never want to avoid calling base.OnFormClosing() when the operating system is shutting down and you call it after your customization so that the client program can overrule your decision if needed.

Make it even more resilient by subscribing the FormClosed event in your main class so you know that the subFormCreated variable needs to be set to false . Note that you don't need that variable, you could just set the subFormSearch variable back to null. So, roughly:

private void displaySubFormSearch() {
    if (subFormSearch != null) {
        subFormSearch.WindowState = WindowState.Normal;
    }
    else {
        subFormSearch = new SubForm(listaPersonas, actualMostrado);
        subFormSearch.FormClosed += delegate { subFormSearch = null; };
    }
    subFormSearch.Show();
}

With the additional detail that you ensure that you restore the window in case the user minimized it previously. Now it is solid. You may need properties to pass updated listaPersonas and actualMostrado, it isn't clear.

You really don't need to override anything here. Just handle the FormClosing event and set e.Cancel = True . Plus make your form invisible in the same handler. In the first form, make a class level object of your second form and call its ShowDialog() upon Search button's Click. Lastly make sure your OK and Cancel buttons have their DailogResult property set appropriately. Roughly it would look like this:

class Form1
{
     private Form2 dlg;

    private void btnSearch_Click(object sender, EventArgs e)
    {
        if(dlg==null) dlg = new Form2();
        dlg.ShowDialog(this);
    }
}

class Form2
{
    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
        this.Hide();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM