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.
Related
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.
Ok, I have a question about the Form Controlbox. I was wondering if it is possible to change or add what the exit button does on the form.
I can easily minimize, maximize and exit the form no problem. But this is what I am facing.
My app has an access login. After you log in it comes to the main form. I have a log out button when pressed, it goes back to the login form.
However, if you press the exit button, it exits the main form, and the program is still running, but with no way to bring the login form up.
So what I am trying to do is, when the main form is exited through the red X I want it to go to the login.
I can go the complex route: borderless form, movable form, custom buttons and etc., etc.,
I think it would be easier to change or add the exit button to return to the login form. Is this possible?
Move the logic out of your button click event, into a separate method.
private void button1_Click(object sender, EventArgs e)
{
OverrideFormExit();
}
private void OverrideFormExit()
{
// execute the code that was previously in button1's click event
}
Now you can subscribe that same method to your Form's Closed event, so that it executes when the user closes the Form.
For example, place the following in your Form's constructor:
FormClosed += (s, e) => OverrideFormExit();
Alternatively, you can subscribe to the main Form's Closed event from within the Login Form, when you instantiate the main Form. I'm guessing at what your code looks like here, obviously.
private void ShowMainForm()
{
FormMain frmMain = new FormMain();
frmMain.Show();
frmMain.FormClosed += (s, e) => this.Show();
this.Hide();
}
I am just wondering how can I detect when a form is closing from ANOTHER FORM, Say I have my main client open another form open called sender, how would I detect when the sender form is closing from the main client form?
Attach an event handler to the form's closing event.
This will allow you to do whatever it is you want to do when the form closes.
You can attach, from the "ANOTHER FORM", an event handler to the FormClosing event
form.FormClosing += (sender, eventArgs) =>
{
//Do your magic here
};
There is also a System.Windows.Forms.Forms.Closing event but it has been deprecated since .NET 2.0
It can be done easier than with an event:
if (!otherForm.IsDisposed)
{
// otherForm is still open
}
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 made a simple test application for the issue, two winforms each containing a button.
The button on the first form opens the other form when clicked. It also subscribes to keyup events.
The second form has its button set as "AcceptButton" and in the Clicked event we sleep for 1s and then set DialogResult to true (the sleep is to simulate some processing done)
When enter is used to close this second form the KeyUp event of the button on the first form is triggered, even though the key was released well before the second had passed so the second form was still shown and focused.
If any key other then enter is pressed in the second form the event is not triggered for the button on the first form.
First form:
public Form1()
{
InitializeComponent();
buttonForm2.KeyUp += new KeyEventHandler(cntKeyUp);
}
void cntKeyUp(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyCode.ToString());
}
private void buttonForm2_Click(object sender, EventArgs e)
{
using (Form2 f = new Form2())
{
f.ShowDialog();
}
}
Second form:
private void button1_Click(object sender, EventArgs e)
{
Thread.Sleep(1000);
this.DialogResult = DialogResult.OK;
}
Does anyone know why the event is triggered for the button on the non active form and what can be done to stop this from happening?
You're making a blocking call, then closing the form, before the WM_KEYUP message is sent.
By the time the message is sent, the second form is gone, so currently focused control is on the first form.
You can solve this by calling BeginInvoke in the second form's click handler to only hide the form in the next message loop (after the KeyUp)
One way around:
You can verify in cntKeyUp if the sender is the Form that you expect then you process it, otherwise ignore.