Is it possible to detect a form closing from another form.
For example.
If I had a mainForm that opens subForm, can I detect within the mainForm that the subForm has closed and execute code?
I understand I could create an event handler within the subForm, but this is not really what I'm after because what I'm about to do after the subForm closes, is within the mainForm (changes to mainForm).
The FormClosed event is public, so you can create a handler from the main form.
//Inside main Form. Click button to open new form
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.FormClosed += F2_FormClosed;
f2.Show();
}
private void F2_FormClosed(object sender, FormClosedEventArgs e)
{
MessageBox.Show("Form was closed");
}
Take a look at the public FormClosedEvent. Since the modifier is public, you're able to do something like the following example:
SubForm subForm = new SubForm();
subForm.FormClosed += delegate
{
MessageBox.Show("subForm has closed");
};
subForm.ShowDialog();
The above example creates a new form (of type SubForm), adds a new event handler to display a message box telling the user that the form has closed, and finally uses the ShowDialog() method which will prevent the user accessing the main form until the sub form has been closed.
The usual case for this is a "Modal Dialog" (like Message Box and its Family).
Every form can be opened as Modal Dialog, by using ShowDialog() isntead of Show().
Otherwise the event way is the only way.
Related
I am trying to make one windows application which contains two forms. In form1(Parent) i created one button for open second form. On that button click event i want to close form1(parent) form and open form2(child) without closing form2, but when i am press that button both forms are closed so how can I do it?
Rather than using .Close() consider using .Hide() on your parent form, this shouldn't dispose of it but rather have it hidden.
Note that exiting out of your Child form means your application won't exit. To circumvent this you should consider subscribing to the OnFormClosed event to handle the form closure.
If you look in "Program.cs" there is a form to start with.
When this form is closed, the application is terminated.
enter image description here
It should be used as a way to hide the startup form.
Even if the child form is closed with the start form hidden, the program does not end.
As #Ae774 said, you need to handle it separately.
If you want to close form1(parent) form and open form2(child) form without closing form2 by click the button, you can refer to the following code:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
Hide();
f2.ShowDialog();
Close();
}
If you want to open the parent form after the child form is closed, you can refer to this code:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
Hide();
f2.ShowDialog();
Show();
}
Here is the test result
In winform application I have a main form and other form. I want to trigger the event of FormClosing of the other form when I click "x" in the main form.
#Update:
Code:
In the Program:
frmMain frm = new frmMain();
frm.ShowDialog();
In frmMain:
private void btnFrm2_Click(object sender, EventArgs e)
{
Frm2 f2 = new Frm2();
f2 .Show();
}
In Frm2:
private void frm2_FormClosing(object sender, FormClosingEventArgs e)
{
//something
}
How can I trigger the event frm2_FormClosing when I close frmMain?
I know I can trigger it when I closing frm2, but I want to trigger it on closing frmMain.
Using observer pattern you can make notification to subscribents (child forms) when FormClosing or any other action happend on main form. In a handler of subscribent you can raise FormClosing event of it (subscribent, childform) or do whatever you want.
Main form is a subject
Child forms subscribe to the subject (main form)
Main form raises notify event within an action of your choice (possibly formClosing in your case)
All subscribents gets notified (their "notified" event is raised)
Inside that "notified" event you do whatever you want, e.g. raise formClosing event of the subscribent (child form)
I believe this pattern is straight-forward and very flexible. I use it to update data in many-to-many related forms.
I have a C# winform called Form1, and this winform has a list and a button.
I added a click() event to the button, and a doubleclick() event to the list.
Both events call to the same method: (in form1.designer.cs)
this.myList.DoubleClick += new System.EventHandler(this.myMethod);
this.myButton.Click += new System.EventHandler(this.myMethod);
In myMethod, I want to do the following operations:
open a new winform of kind Form2, and make it the active winform.
close the caller winform (of kind Form1), there is no need for this form anymore.
I did it like this: (in form1.cs)
private void myMethod(object sender, EventArgs e)
{
Form2 frm = new Form2();
this.dispose();
}
when myMethod is being called by list doubleclick event, when myMethod ends, there is a null pointer exception.
When it's being called by the button click event, it works properly.
I tried this.close() as well, and got the same behavior.
my questions:
How should I write myMethod properly so it will make the wanted operations for the button click event and also for the list doubleclick event?
What is the difference between the button and the list? why does it work properly for the button, but crashes for the list?
Thanks
You can hide the Form1 and show Form2. This will raise some issue like closing Form2
won't close Form1.
this.Hide();
var form2 = new Form2();
form2.ShowDialog();
I have some problems with Form control focusing.
On form1 I click a button and run the code below:
private void btnTest_Click(object sender, System.EventArgs e)
{
form2 = new Form2();
Application.Idle += new EventHandler(Application_Idle);
form2.Show();
form2.Activate();
form2.textBox1.Focus();
Form3 form3 = new Form3();
form3.ShowDialog();
}
Then, after this CLR I run the event Application_Idle on which I add a method that must focus on the textBox2 control..
private void Application_Idle(object sender, EventArgs e)
{
form2.textBox2.Focus();
form2.textBox2.Select();
form2.textBox2.Focus();
Application.Idle -= new EventHandler(Application_Idle);
}
But when I click the button on form1, I see Form2 showing, Form3 showing and then Application_Idle method raise, but form2.textBox2 control doesn't get focused...
If I comment out the form3.ShowDialog(); line it's works fine, but how do I focus a form element with another form activation?(form3.ShowDialog()) ?
Remark added:
Problem in also is I have a strict architecture and all I can change is Application_Idle method.
The issue you are having is with modality:
Forms and dialog boxes are either modal or modeless. A modal form or dialog box must be closed or hidden before you can continue working with the rest of the application.
Dialog boxes that display important messages should always be modal. The About dialog box in Visual Studio is an example of a modal dialog box. MessageBox is a modal form you can use.
Modeless forms let you shift the focus between the form and another form without having to close the initial form. The user can continue to work elsewhere in any application while the form is displayed.
When you use ShowDialog, the form that is shown prevents the caller from returning control until the dialog box is closed. If this is not the desired effect, you can use the Show method.
You could focus the textfeld, when the form itself got the focus:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
this.GotFocus += (s, e) =>
{
this.textBox2.Focus();
};
}
}
As John Koerner stated, you cannot set focus to Form 2 while Form 3 is open because of modality.
Since you stated that a user input in Form 3 is necessary to proceed, you should change your approach. You can place a listener watch for Form 3's closing. Only then can you set the focus somewhere else
form3.FormClosed += Application_Idle
I have the following problem:
I open multiple modal forms in a stack (for example, form1 opens modal form form2 which in turn opens modal form form3, etc.). I would like to hide the entire stack.
I tried calling the Hide method or setting the Visible property on the parent, but this only hides the parent. I also tried hiding every form individually, but then I have to call ShowDialog on each of the forms which locks the thread in which I call the aforementioned method.
Is there be a way to set the modal dialogs so that they inherit the status of the parent and get hidden in a cascade just by setting the property on the first form?
I'm also open to other suggestions.
To re-show a form you hid by setting obj.Visible = false just set obj.Visible = true, not ShowDialog.
ShowDialog initiates a message loop, which will cause confusion since the dialog is already running a message loop.
Since you're talking about modal dialogs, it would be the last one opened that would commence this action. Open every form as in the following example, and then Hide() that last one.
public partial class Form1 : Form
{
Form2 frm2 = new Form2();
public Form1()
{
InitializeComponent();
frm2.VisibleChanged += frm2_VisibleChanged;
Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
frm2.ShowDialog();
}
void frm2_VisibleChanged(object sender, EventArgs e)
{
if (frm2.Visible == false) Hide();
}
}