C# Why does form.Close() not close the form? - c#

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?

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.

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().

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.

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.

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.

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.

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();
}

Related

Close WinForm On Button Click

I have this syntax on my buton press event, but when I press it - the form does not close.
What is the proper way to close the form on the button press event?
private void btnClose_Click(object sender, EventArgs e)
{
IxalocToes nip = new IxalocToes();
nip.Close();
}
This method btnClose_Click runs inside your forms class
Forms have a method call Close, calling Close() or this.Close() inside the form will close it
private void btnClose_Click(object sender, EventArgs e)
{
IxalocToes nip = new IxalocToes();
nip.Close();
Close();
}
As suggested by many and it is right, calling
this.Close() or
Close()
will close the form. As you want to know why nip.Close() is not working, it's because the button is in a FORM but when you call nip.Close() instead of this.Close(), it will close the new object created, not the one on which the button resides.

Execute function on another, already open, form

I have a form with a datagridview inside of it.
When you doubleclick on a row from the datagridview, another form will open, which is basically a form where you can edit the data you just double-clicked.
There are a 3 buttons in this "edit" form, a delete, update and a return to main form button.
When finished with what you were supposed to do on this form, it closes.
My question is;
When this form closes, I want the data that is inside of the datagridview in the main form to refresh, how can I call that function on the main form from the edit form.
Keep in mind that I already have a reload function, let's say it's called refreshData();.
if you open the edit form as a modal window, the ShowDialog() call is blocking, so if you put the refreshData call after that it will execute after the edit form is closed:
var editForm = new EditForm(...);
var result = editForm.ShowDialog();
if (result == DialogResult.OK)
{
refreshData();
}
If you used .ShowDialog(), then just put the refresh function under this line of code.
The program will continue with the
private void cell1_DoubleClick(object sender, System.EventArgs e)
function.
So your code will look similair to this;
private void cell1_DoubleClick(object sender, System.EventArgs e)
{
//Your previous code ....
//The part where you open the EditForm
MyEditForm.ShowDialog();
//After it has been closed the program will continue to execute this function(if it has not been ended yet)
RefreshData();
//Since this function is running from your main form, the function RefreshData() will be executed on your main form aswell
}
No need to check some dialog results at all.
I think this will work:
Add a property DatagridviewForm of type DatagridviewForm (you have probably an other name/type) to AnotherForm. In the part where you call anotherForm.ShowDialog, add the following code:
anotherForm = new AnotherForm();
anotherForm.DatagridviewForm = this;
anotherForm.ShowDialog();
anotherForm.Dispose();
In the close handler of AnotherForm, update or refresh the data:
private void AnotherForm_FormClosed(object sender, FormClosedEventArgs e)
{
DatagridviewForm.refreshData();
}
You can access the data when the form is closing
Form MyEditForm;
private void cell1_DoubleClick(object sender, System.EventArgs e)
{
if (MyEditForm==null)
{
MyEditForm=new MyEditForm();
MyEditForm.FormClosing += refreshData;
}
MyEditForm.ShowDialog();
}
private void refreshData(object sender, EventArgs e)
{
var myDataObj=MyEditForm.getData();
}

Closing multiple windows form with single click

I want to close two forms at the same time. I have one main form that starts with program. when user click button, the main form will hide and other form will pop up. on the second form if user click "back to main " button, it should hide second form and show main form. But the problem is if user tries to close the second form it should close the main form as well. How can i close the main form as well
I would just use the Application.Exit() for what is requested by this thread.
Application.Exit();
UPDATE: corrected
I had said this will not call the form closing events but in documentation it does actually call it here is a link to the documentation
http://msdn.microsoft.com/en-us/library/ms157894(v=vs.110).aspx
It was better if you specified what codes you wrote for going back to main form, so I could help you by changing your codes. But now because I don't know how you did it, I have to write codes for both of those tasks.
It can be possible using a Boolean variable to do what you want. Follow bellow codes:
public partial class MainForm : Form
{
//"Click" event of the button that should opens the second form:
private void goToSecondForm_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(); //Or you can write it out of this method.
this.Hide(); //Hides the main form.
f2.ShowDialog(); // Shows the second form.
this.Show(); // Shows the main form again, after closing the second form using your own button.
}
}
public partial class Form2 : Form
{
bool selfClose = false; //False shows that user closed the second form by default button and true shows that user closed it by your own button.
//"Click" event of the button that should closes just the second form and returns user to the main form:
private void ownCloseButton_Click(object sender, EventArgs e)
{
selfClose = true; //Means user clicked on your own button.
this.Close(); //So the program closes the second form and runs f2_FormClosed method, but because selfClose became true here, happened nothing there and program will go back to goToSecondForm_Click method in the main form and will run this.Show() .
}
//"FormClosed" event of the second form :
//Whether user clicked on your own button or on the default one, this method will run.
private void f2_FormClosed(object sender, FormClosedEventArgs e)
{
if (!selfClose) //It means user didn't click on your own button and both of forms must be closed .
Application.Exit(); //So the program closes all of forms (actually closes the program) and couldn't access to any other commands (including this.Show() in goToSecondForm_Click method).
}
}
As others have said, you need to somehow call .Close() on the main form when your child form is closed. However, as you've pointed out, you don't have a reference to the main form automatically in your child form! That leaves you with a few options.
1. Exit the application immediately.
This is done by calling Application.Exit(); in your child form's "back to main" button's click event handler. It will immediately close all forms, which might simply be what you want.
// .. ChildForm code ..
void OnBackToMainClicked(object sender, EventArgs e)
{
Application.Exit();
}
2. Pass a reference to the main form to the child form.
This is probably the most common way to solve this problem in general. When you create your child form in your main form, you'll need to pass a reference as follows:
// .. MainForm code ..
void OnGoToChildForm(object sender, EventArgs e)
{
var childForm = new ChildForm(this);
childForm.Show();
}
// .. ChildForm code ..
private MainForm mainForm; // This is where the child form will keep a reference to
// the main form that you can use later
public ChildForm(MainForm mainForm)
{
// This is the child form's constructor that we called above,
// and it's where we'll save the reference to the main form
this.mainForm = mainForm;
}
// This also needs to be the event handler for the close event
void OnBackToMainClicked(object sender, EventArgs e)
{
this.Close();
mainForm.Close();
}
3. Add an event handler on the child form's FormClosed event. This is a safe way to solve the problem if you are concerned about keeping your main application logic under the control of the main form. It's similar to the solution suggested by Lamloumi above, but it's all done in the main form's code.
// .. MainForm code ..
void OnGoToChildForm(object sender, EventArgs e)
{
var childForm = new ChildForm(this);
childForm.FormClosed += new FormClosedEventHandler(SecondForm_FormClosed);
childForm.Show();
}
void SecondForm_FormClosed(object sender, EventArgs e)
{
// Perform any final cleanup logic here.
this.Close();
}
Form1 _FirstForm = New Form1();
Form2 _SecondForm = New Form2();
MainForm _MainForm = new MainForm();
_FirstForm.Close();
_SecondForm.Close();
_MainForm.Show();
Normally , in the Home form you have some ting like this :
SecondForm second= new SecondForm ();
second.Show();
this.Hide();
In the SecondForm you must ovveride the event of closure like this :
public class SecondForm :Form{
public SecondForm()
{
InitializeComponent();
this.FormClosed += new FormClosedEventHandler(SecondForm_FormClosed);
}
void SecondForm_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
}
To be sure that your application is closed after you close the form. because the Home from is still active and hidden if you don't.
use this in Form2
private void button1_Click(object sender, EventArgs e)
{
Form1.FromHandle(this.Handle);
}
There Handle are the same now ;
hope this work.

Invoke event handler on a different form after closing the active form

I have a C# application in which I need specific or a function to execute on a form after closing the active form.
The form in which I need the code to excute becomes the active form after the previous active form is closed. So in a nutshell after closing this form the form in which I need the event handler or function to run will then become the active form. Is there a way that this is possible?
I have tried the Form_Enter event handler on the form that becomes active after the other form is closed, but that did not work.
I believe you can achieve what you are trying to do more simply. The code you use to show Form2 from Form1 (Main), you can add your code there like so:
Class Form1 {
private void button_click(object sender, EventArgs e) {
Form2 newForm = Form2();
newForm.ShowDialog(); // To prevent the main form carry on
// Your code needed to be excuted
}
}
In the form closing event set the DialogResult as follows:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.DialogResult = System.Windows.Forms.DialogResult.Yes;
}
When you open the form look for the response as follows:
if (Form1.ShowDialog() == DialogResult.Yes)
{
////do stuff.
}
I hope this helps.

How to safely close form soon after it's shown?

From my main form, I open a couple of other forms on mouseclick, like so:
Main Form:
...
private void btn_Click(object sender, EventArgs e){
frmNewForm newForm = frmNewForm();
newForm.Show();
}
In the new form, I'd like to check if there's any data to show, and if not immediately close the form.
New Form:
...
public frmNewForm(){
InitializeComponent();
// check if opening this form makes sense
if(noData){
Close();
}
}
However, I get an exception thrown at frmNewForm.Show(): The object can't be accessed.
I apologize if the translation isn't exactly the same as Visual Studio's: I'm working with another language version.
Anyway, what can I do to safely close frmNewForm?
You don't want to do it in the constructor for the new form. Rather, you need to do it on the Load event so that it finishes loading before you close it.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.load.aspx
private void Form1_Load(object sender, EventArgs e)
{
if (noData) this.Close();
}
Alternatively, if you know you won't need to open the form, check before showing it!
If noData is a public Boolean property of your frmNewForm class, you can do this:
if( !newForm.noData )
{
newForm.Show();
}
Make sense?

Categories