this is my scenario and hope you can solve it for me
I have a MDI container form called "MainForm". In MainForm there is a simple form call "Form1". In Form1 there is a button. every time you pushed it, It open a new form which instance of "Form2". The followng code is click button event.
Button_Click()
{
Form2 frm=new Form2();
frm.mdiparnt=this.MdiParent;
this.addOwnedForm(frm);
frm.Visible=true;
}
and the following code tries to close owned forms when the user close Form1
Form1_CloseEvent()
{
foreach(var item in this.ownedForm)
{
item.close();
}
}
But when the debugger steps into close event, just close Form1, and the form2 instances remain open. what should I do to solve it
I think you are not setting up the event. Do it like this.
Add it to your Button_Click() method:
this.FormClosed += Form1_FormClosed;
Here is the method:
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
foreach(var item in this.ownedForm)
{
item.close();
}
}
first of all this code does not compile!
you have several syntax errors: mdiparnt, addOwnedForm, ownedForm, close
you are probably not sharing your actual code and that's gonna be a problem to help you if it's not your code.
now in Button_Click() event you are doing
frm.mdiparnt=this.MdiParent;
this.AddOwnedForm(frm);
even though you only need
this.AddOwnedForm(frm);
or an exception will be thrown. i've checked this code and it's working just fine
Related
PROBLEM SOLVED
SHORT STORY
I want to detect "FormClosing()" event through different forms, ie, when form1 is closed that is instantiated within form2, can form2 detect when user presses exit in form1?
LONG STORY
My team and I are working on a windows form application. Project has two forms: one is the main form page and the other is accessed via this main form. Main form looks like this:
And the second one looks like this:
If you press "Ekle/Sil" buttons within the main form, you are directed to form 2 where you can edit database entries. When you press "Sayfayı Yenile" button in the main form, the content of the text areas are refreshed by re-fetching entries from the database.
My problem is, I want to automatically refresh the main form when the user closes the second form. My research suggests I should use an "FormClosing()" event to detect a closing form. However, I want to detect this from the main form. Instantiating main form in second form's source code doesn't seem to be a reliable solution. Anyone can tell me how to do this?
EDIT
I solved the problem:
1) Created a public method within the main form that refreshes the page.
2) Send "this" property from the main form when creating the second form.
3) Added an "FormClosed()" handler within the second form that invokes this public method.
Still, I'm looking for a better solution.
EDIT 2
Better solution InBetween's answer
Simply use the Form.Closed event of the new child windows form. Everything is handled from the main form:
void EkleSil_Clicked(object sender, EventArgs e) //or whatever method is called when button is clicked
{
var newChildForm = new ChildForm();
newChildForm.Closed += childFormClosed;
newChildForm.Show();
}
void childFormClosed(object sender, EventArgs e)
{
((Form)sender).Closed -=childFormClosed;
updateShownData();
}
You can create a event in the second form and raise it when the form is closing .
Handle the event in the main form and refresh the main form when the event is raised
Another option would be to pass Form1 as an argument to Form2. Then use the Form.Closing event in Form2 and use the Form1 reference to trigger something.
Form1 form1Ref;
public Form2(Form1 mainform)
{
form1Ref = mainform;
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
form1Ref.SomeMethod();
}
What's the proper way to close application with clicking on X in built in menu strip. Let's say that my Form1 opens Form2, when I close my Form2 my Form 1 stays open. What I want to achieve is that my application stops when I close my Form2. Does anybody know how to achieve this and how to reference it to X button on built in menu strip.
Try this:
Application.Exit();
In case it doesn't work, you have to provide more information and be more specific with code
In Form2 you could Register to the Closing Event in constructor something like this:
public Form2()
{
this.FormClosing += Form_OnClosing;
}
Then in the event close the Form1 and/or exit the application
private void Form_OnClosing(object sender, EventArgs args)
{
Application.OpenForms[0].Close();
Application.Exit();
Environment.Exit();
}
Try it
form2 F2 = new form2();
F2.ShowDialog()
I think you have a trouble with create new form children
I have a main form, in the class of this form, I declare another form. This form lives with the main form until the main form is unloaded. There is a button on the main form, clicking this button will show the member form (I mentioned above). I want to prevent the member form from closing when user closes that form and I added the following FormClosing event handler for that form:
private void MemberForm_FormClosing(object sender, FormClosingEventArgs e) {
if(e.CloseReason == CloseReason.UserClosing){
e.Cancel = true;
Hide();
}
}
That works OK for that form. However if user closes the main form, this form is not closed, and it's hidden somewhere making my application seem to run silently. I want this form also to be closed. This is very simple by adding some FormClosed event handler for my main form to close the member form manually. Closing it manually is OK, but why do I have to do that? It seems that when user closes the main form, the FormClosing event of the member form is fired with a parameter FormClosingEventArgs passed in and the CloseReason is the same as the CloseReason of the main form (which is UserClosing). I don't understand this, I thought the CloseReason of the form is UserClosing only when user clicks on the X button, I thought the CloseReason for my member form is something like "MainFormClosing".
Is there some way to close the member form automatically as by default?
UPDATE
Here is the method showing the member form (showing it as a dialog):
private void ShowMemberForm_Click(object sender, EventArgs e){
memberForm.ShowDialog();
}
But I don't think this matters, because when I load my main form, even I don't need to click on the ShowMemberForm button, and try closing my main form first, it doesn't still close the member form.
Thanks!
UPDATE
There is something strange here, I've tried commenting out the line e.Cancel = true, or even all the FormClosing event handler and the problem is still there. This is so strange, it works OK before, I've just added the member form and this form relates to some Thread handling, but the thread starts only when a button on the member form is clicked. I didn't click that button.
What I have done in the past is set a flag when programatically closing
so in the MemberForm
private bool _ForceClose = false;
public void ForceClose()
{
_ForceClose = true;
this.Close();
}
private void MemberForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(!_ForceClose)
{
e.Cancel = true;
Hide();
}
}
Then in your MainForm you can call
memberForm.ForceClose();
From within your MainForms FormClosing method or from your MainForms Dispose() or Deconstructor.
It's low tech, but it works. Im not sure if you should put _ForceClose = true in your MemberForm's Dispose method, i'm fairly certain when it gets there its already been closed BUT it couldn't really hurt.
I have a windows forms question:
Program.cs:
Application.Run(new frmStart());
frmStart: on btnLoad_Click,
frmLoad formLoad = new frmLoad();
formLoad.Show();
this.Hide(); // if I do a this.Close(); after it shuts down and doesn't get to show the form
frmLoad: on btnCancel_Click:
Application.Exit();
// or this.Close();
// or even: base.Close();
The form disappears but the program doesn't end, I still have to press the blue "Stop Debugging" to make it stop.
I have been looking... I know it is possible to make the program really stop, and not just freeze when you close the second form, even if you don't keep the first form on the screen, but can't remember and can't figure out how.
Ack, -1 on Application.ExitThread!
The issue is that you haven't closed the main form. The simplest way is to hook onto the 2nd form's Closed event and have it close the main form. For example the code to open the 2nd form changes to:
var newForm = new frmLoad();
newForm.FormClosed += (closedSender, closedE) => Close();
newForm.Show();
Hide();
This essentially sets up so that when the frmLoad form closes, the main form calls it's Close() method. I used a Lambda expression for the event handler, but you can just as easily create a private method accepting an (object sender, EventArgs e) and point .FormClosed at it.
*Edit: Sorry, missed that you only want to close on certain state. In which case on your frmLoad, create a public property such as:
public bool UserCancelled
{
get;
private set;
}
where the Cancel button sets this to True before closing the form. Your event handler in the main form changes to:
var newForm = new frmLoad();
newForm.FormClosed += (closedSender, closedE) =>
{
if (newForm.UserCancelled)
Close();
};
newForm.Show();
Hide();
In frmStart add:
public static frmStart Current;
Then in the constructor add:
Current = this;
Then in frmLoad: on btnCancel_Click:
frmStart.Current.Close();
You really should call Close() on both. That's the only clean way as otherwise the first form never is told to close down and doesn't clean up.
You may know that it's safe to do this, but someone else working on the code later may add code in the OnClose in the first form that they need called. They will say not nice things about you when they finally figure out why their code is not called.
If you close both, then your app will exit.
Please use the Application.ExitThread() method, the method exits the message loop on the current thread and closes all windows on the thread.
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.exitthread
I vote yuck on all the answers. Override Form Closing in your primary form and close the secondary form first.
how do I check if a form is closed?
I want to reload a listview's items when I close another form.
What I'm doing is:
Form1 = form with ListView
Form2 = form with TextBoxes
Opening a new form.
Creating a new folder via a textbox.
When I press "Add" in Form2 I want to reload the "ListView" on Form1.
So how am I supposed to do this?
And sorry for my bad English :(.
The simplest answer is to make a public method on Form1, let's call it RefreshList() and in your button click event on Form2, you simply call Form1.RefreshList. Here's a quick sample:
Form 2:
public Form1 ParentForm { get; set; }
private void Button_Click(object Sender, EventArgs args) {
{
// After the rest of your handler
if(ParentForm != null)
ParentForm.RefreshList();
Close(); // Close Form2 here, we're done!
}
Form 1:
private void ShowForm2()
{
Form2 form2 = new Form2();
form2.ParentForm = this;
form2.Show();
}
public void RefreshList()
{
// do your refresh here
}
Initially you mention that you want to do this when Form2 closes, but then later you mention that you want to do it "When I press "Add" in Form2 I want to reload the "ListView" on Form1." As others have mentioned, you can use the Closed event, so I took this approach to address your second case.
In Form1, you can subscribe to From2's FormClosed event.
You can handle the form Closing event as the Closed Event is obsolete if you are using anything above dot net 1.1
You can handle the FormClosed event if you simply want to react to when a particular form is closed. If you want to take it a step further, there is a FormClosing event that you could also handle and even prevent the form from closing if need to.
Having Form1 add an event handler to Form2's FormClosing event is an excellent option. However, there is an even simpler solution if Form2 is a dialog window. In other words, if it's OK for Form1 to be effectively locked and disabled while Form2 is displayed, you can simply show Form2 as a dialog window. Dialog windows show synchronously, so you can simply update the list immediately after showing Form2 and it won't hit that list-updating code until after Form2 is closed. For instance:
form2.ShowDialog(this);
updateList();