16

I have a WinForm that I create that shows a prompt with a button. This is a custom WinForm view, as a message box dialog was not sufficient.

I have a background worker started and running. I also want to exit the while(aBackgroundWorker.IsBusy) loop if the button on myForm was clicked.

//MyProgram.cs

using(CustomForm myForm = new CustomForm())
{
    myForm.Show(theFormOwner);
    myForm.Refresh();

    while(aBackgroundWorker.IsBusy)
    {
        Thread.Sleep(1);
        Application.DoEvents();
    }
}

Right now, in the CustomForm the Button_clicked event, I have

//CustomForm.cs

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

Do I need to add more code to the CustomForm class, or the location where I declare and initialize the form in order to be able to detect a closure?

tshepang
  • 12,111
  • 21
  • 91
  • 136
jkh
  • 3,618
  • 8
  • 38
  • 66
  • What form/class do you want to notify of the close of the window? – Decker97 Jan 05 '12 at 22:16
  • 1
    Writing this code makes no sense. Presumably there's something *after* this while loop. Move that code to the RunWorkerCompleted event handler for that BGW. – Hans Passant Jan 05 '12 at 22:18

7 Answers7

32

To detect when the form is actually closed, you need to hook the FormClosed event:

    this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);

    void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Do something
    }

Alternatively:

using(CustomForm myForm = new CustomForm())
{
    myForm.FormClosed += new FormClosedEventHandler(MyForm_FormClosed);
    ...
}

void MyForm_FormClosed(object sender, FormClosedEventArgs e)
{
    // Do something
}
competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • Other reference that helped me a bit to understand : http://www.dreamincode.net/forums/topic/185541-trigger-event-in-another-form/ `private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.FormClosed += new FormClosedEventHandler(form2_FormClosed); form2.Show(); } void form2_FormClosed(object sender, FormClosedEventArgs e) { MessageBox.Show("Form 2 Closed!"); } ` – Dorian Grv Dec 19 '17 at 13:08
5

You might be going overkill. To show a form like a dialog window and wait for it to exit before returning control back to the calling form, just use:

mySubForm.ShowDialog();

This will "block" the main form until the child is closed.

Dracorat
  • 1,184
  • 7
  • 12
1

Make sure your background worker supports cancellation and as others have pointed out use the form closed event handler. This code should point you in the right direction:

using(CustomForm myForm = new CustomForm())
{
  myForm.FormClosed += new FormClosedEventHandler(ChildFormClosed);
  myForm.Show(theFormOwner);
  myForm.Refresh();


  while(aBackgroundWorker.IsBusy)
  {
    Thread.Sleep(1);
    Application.DoEvents();
  }
}

void ChildFormClosed(object sender, FormClosedEventArgs e)
{
    aBackgroundWorker.CancelAsync();
}
evasilchenko
  • 1,862
  • 1
  • 13
  • 26
0

Note that this.Hide(); is not the same as this.Close(); in the actual dialog your overriding the closed event

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
dcarl661
  • 177
  • 3
  • 9
0

Handle the FormClosing event of the form to be notified when the form is closing, so you can perform any cleanup.

Kekoa
  • 27,892
  • 14
  • 72
  • 91
  • The form is a general form used throughout my application, so I can't say in CustomForm.cs OnFormClosing - clean up this specific part of MyProgram.cs – jkh Jan 05 '12 at 22:18
  • You might need to do it in all forms if the cleanup is specific to the form. – Kekoa Jan 05 '12 at 22:19
0

You should be able to hook into the FormClosing and FormClosed events.

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosed.aspx

Closing is before it's closed. Closed is after it's closed.

user1231231412
  • 1,659
  • 2
  • 26
  • 42
0

A couple things...

First, it appears that loop is there in order to prevent execution form proceeding while the dialog is open. If that is the case, change you .Show(parent) to .ShowDialog(parent). That will also take care of the rest of your question.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89