10

I have a button click event handler with the following pseudo code:

private void btnSave_Click(object sender, EventArgs e)
{
  if(txt.Text.length == 0)
     this.Close();
  else
     // Do something else

  // Some other code...
}

This is just some simple code, but the point is, when the text length equals zero, I want to close the form. But instead of closing the form the code executes the part // Some other code. After the click event handler is completely executed, then the form is closed.

I know, when I place return right after this.Close() the form will close, but I'd like to know WHY the form isn't direclty closed when you call this.Close(). Why is the rest of the event handler executed?

Martijn
  • 24,441
  • 60
  • 174
  • 261

7 Answers7

15

The rest of the event handler is executed because you did not leave the method. It is as simple as that.

Calling this.Close() does not immediately "delete" the form (and the current event handler). The form will be collected later on by the garbage collector if there are no more references to the form.

this.Close() is nothing than a regular method call, and unless the method throws an exception you will stay in the context of your current method.

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • But intuitively I would except that when calling this.Close() the form will be closed, but this ain't the case. Thanks for the clarification. – Martijn Oct 12 '10 at 08:49
  • @Martijn: So the form stays open and does not close at all? Can you show what "some other code" is doing then? Or can you post a simple sample showing that behaviour? – Dirk Vollmar Oct 12 '10 at 08:55
  • @0x3a: Incorrect. The form executes all the code in the event handler and then closes the form. You have already answered my question :) I was wondering why `Close()` doesn't destroy the form at the moment `Close()` is called. – Martijn Oct 12 '10 at 08:57
  • @martijn it will be closed when calling .Close() however closed is not destroyed. Considere this code: form.Close(); releaseResources(); where the last method calls takes a long time. Why would you want the user to see an unresponsive form when after all they will be able to do nothing more with it. In other words: There are times where you wish to close the form but still run some form code – Rune FS Oct 12 '10 at 08:57
  • @Rune FS: In that case, what is the purpose of a closed form? What kind of things aren't possible anymore? I can't imagine what a closed form means. – Martijn Oct 12 '10 at 09:01
  • 3
    @Martijn it means that the forms has been visually closed. It's no longer shown on screen and the _user_ can't interact with it. If you close a drawer do you expect it to be destroyed? or do you simply accept that you have to reopen it before you can interact with what you keep in the drawer? it's the same with closing a form. If you wish to interact with whats on the form you need to reopen it but just as the drawer is not destroyed so is also true for the form – Rune FS Oct 12 '10 at 09:20
  • @Rune FS: Thanks for the further explanation. Like the comparison with the drawer, it makes sense now! Thanks again – Martijn Oct 12 '10 at 09:24
  • `.Close()` does not close the form immediately, it sends a message to the message pump requesting the form be closed _after all current work is done_, i.e. when all other messages have been processed. – Kris Vandermotten Oct 11 '13 at 08:55
  • @Rune FS Unless the Form is a modal form, Form.Close *disposes* the form, as well. So, you cannot reopen it under any circumstances after that. There is Form.Visible for this behavior(hiding/showing the form). The point here is that .Close() does not return from the section it is called for several reasons. For example, you may call SomeForm.Close() from *another form* or a class or whatever. Close() is just a method like any other. You have to explicitly return from a method that calls Close() if this is what you want. – ThunderGr Dec 05 '13 at 10:44
6

Close only hides the form; the form is still alive and won't receive another Load event if you show it again.

To actually delete it from memory, use Dispose().

vulkanino
  • 9,074
  • 7
  • 44
  • 71
  • 5
    No, this is not correct. `Form.Close()` will dispose the form, i.e. it calls the `Dispose` method. – Dirk Vollmar Oct 12 '10 at 08:46
  • 1
    Not exactly, if the form is an MDI client, and is invisible, Close won't Dispose. Or if the form is a dialog box (ShowDialog called), it won't Dispose either. – vulkanino Oct 12 '10 at 08:49
  • When I use `Dispose()` instead of `Close()` the rest of the code is still executed. – Martijn Oct 12 '10 at 08:52
  • 4
    +1. Thanks `this.Dispose(); this. Close();` worked fine for me :) – Jack Sep 16 '12 at 15:44
3

Answer is simple as you are executing your current method so this.Close() will be enqueued until either you explicitly returned or your current excuting method throws an exception.

TalentTuner
  • 17,262
  • 5
  • 38
  • 63
2

Another possible solution is that if you open a new Form and want to close the current one: if you use newForm.ShowDialog() instead of newForm.Show() it doesn't close the currentForm with currentForm.Close() until the newForm is also closed.

online Thomas
  • 8,864
  • 6
  • 44
  • 85
  • 1
    When closing the form with `this.Close()`, notice if the current form is shown using `f.ShowDialog();` it will return `DialogResult .Cancel`. In the dialog form (callee) I have added `this.Close(); this.Dispose(true);`. Now this dialog seems to be finally closing! \o/ – Junior Mayhé Feb 21 '14 at 15:09
0

Unless the Form is a modal form(opened with .ShowDialog()), Form.Close() disposes the form, as well. So, you cannot reopen it under any circumstances after that, despite of what others may have said. There is Form.Visible for this behavior(hiding/showing the form).

The point here is that .Close() does not return from the section it is called for several reasons. For example, you may call SomeForm.Close() from another form or a class or whatever.

Close() is just a method like any other. You have to explicitly return from a method that calls Close() if this is what you want.

ThunderGr
  • 2,297
  • 29
  • 20
0

Calling MessageBox.Show(frmMain,"a message","a title") adds the form "TextDialog" to the application's Application.OpenForms() forms collection, along-side the frmMain Main form itself. It remains after you close the Messagebox.

When this happens and you call the OK button delegate to close the main form, calling frmMain.Close() will not work, the main form will not disappear and the program will not terminate as it usually will after you exit the OK delegate. Only Application.Exit() will close all of the garbage messagebox "TextDialog"s.

Felinis
  • 47
  • 3
0
private void btnCloseForm_Click(object sender, EventArgs e)
{
FirstFrm.ActiveForm.Close();
}

and if you want close first form and open secound form do this :

private void btnCloseForm_Click(object sender, EventArgs e)
{
FirstFrm.ActiveForm.Close();
}

private void FirstFrm_FormClosed(object sender, FormClosedEventArgs e)
{
SecounfFrm frm = new SecounfFrm ();
frm.ShowDialog();
}

or you can do somting like that :

private void btnCloseForm_Click(object sender, EventArgs e)
{
this.Hide();
}

private void FirstFrm_VisibleChanged(object sender, EventArgs e)
{
if(this.Visible == false)
{
this.Close();
}
}

private void FirstFrm_FormClosed(object sender, FormClosedEventArgs e)
{
SecounfFrm frm = new SecounfFrm ();
frm.ShowDialog();
}