C# - Launch method in MdiParent when one specific MdiChild is closed - c#

I'm actually building a program at school in .net. This is the first time I'm using it and I've got a question.
I got a MdiParent form which has two MdiChildren : a config form, and an articles list form. When you fill the config form, the articles list should appear.
I'm actually using this method in the MdiParent :
private void MotherMdi_MdiChildActivate(object sender, System.EventArgs e)
{
...;
}
But I need to deal with multiple variables because this method is fired every time a mdichild is open or closed ...
Is there a way to call a specific method only when One MdiChild is closed ?
Thanks a lot.

Event FormClosing is raised every time a windows form is closed. You can handle that event and do processing that you need to do when a form is closing.
In the parent form:
private void ParentForm_Load(object sender, EventArgs e)
{
ChildForm childForm = new ChildForm();
childForm.childFormClosed += childForm_childFormClosed;
}
void childForm_childFormClosed(object sender, FormClosedEventArgs e)
{
// Handle processing here
}
In the child form:
public event EventHandler<FormClosingEventArgs> childFormClosed;
private void ChildForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (childFormClosed != null)
{
childFormClosed(sender, e);
}
}
You may want to use FormClosed if that is what you need.
You can also use your own inherited class if you want to pass more information than what FormClosingEventArgs would do.

Related

Is it possible to modify the onload event after the first time a form is opened?

I have an empty onload event that I don't want to call the very first time the form is loaded. Is it possible to load the form, and then when the form closes, it injects another method into the onload event for when the form needs to be opened again?
This is how I want it to be the first time I open a form:
private void MainForm_Load(object sender, EventArgs e)
{
}
This is how I want it to be the next time I open the form:
private void MainForm_Load(object sender, EventArgs e)
{
LoadData();
}
Is this possible?

Form closed event not triggered in parent form

I am having a bit of a head scratch moment at the moment.
I have 2 Forms one being a Parent form and other being the child form.
Inside the Parent form am trying to detect the FormClosed event which I have subscribed to a event inside the Parent form to handle some behaviour.
However the FormClosed event never gets subscribed or triggered when I close the child Form? I am not really sure what am doing wrong? I have even tried FormClosing and nothing gets triggered?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (var frm2 = new Form2())
{
frm2.ShowDialog();
frm2.FormClosed += Frm2OnFormClosed;
}
}
private void Frm2OnFormClosed(object sender, FormClosedEventArgs e)
{
// Implement further behaviour handling.
}
}
ShowDialog() will block execution of code in the calling method until the new form is closed. So you are opening and closing frm2 before you've ever even assigned the EventHandler. Switch your two lines around like so and you should be good to go:
frm2.FormClosed += Frm2OnFormClosed;
frm2.ShowDialog();

Items in checklistbox deleted after form closes

I have a simple c# winform and I'm trying to add a string to it.
e.g.
checklistbox1.Items.Add("string");
the problem is that after I close the form and run the program again, my added string is deleted from the checklistbox and I have to enter it again.
When you close the form, the members associated with it are removed as well. If you want it to be saved, you need to use a method that well save the data for you, such as XML, txt doc, or even a database, depending on the lifespan of the information you want to keep.
If it is only needed while the program is running, you may look into having the information stored in a member in the mainform rather than only just the form with the checklistbox.
Add a public List property to your form.
Create a second ctor for your form and inside your second ctor code
write:
public YourForm(List<string>() strings)
{
foreach(var item in strings)
{
checklistbox1.Items.Add(item);
}
}
You don't have to unload the form when closing. Let the parent form - I assume this is launched from another form - do the unloading/disposing of all the child forms instead. The trick is to make it appear to the user that you're closing the form. Let's say the form containing the checklist is Form2, the function that loads Form2 from the parent form will look like this:
Form2 _form2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (_form2 == null)
{
_form2 = new Form2();
}
_form2.Show();
}
And in the Form2, handle the Closing event like this:
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
Hide();
}
And finally, in the parent form Closing event, you can dispose Form2
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (_form2 != null)
{
_form2.Dispose();
_form2 = null;
}
}
If you need to have the same set of values for all instances of Form2, then you can use Singleton pattern. That's another discussion :)

How I open a form at a time under MDI parent form?

I have a MDI form. Within this MDI there is multiple button to open new forms. Let buttons are btn1, btn2, btn3, btn4.... When I press btn1, form1 is load. when I press btn2, form2 is load... Now I press btn1, And form1 is loaded. If I press again btn1 then another form1 is open. Simultaneously let form1 is open, if I press btn2 form2 is open. But I want to open a form at a time. How I prevent this?
all the answers you got are good so i'm not going to repeat them, just give you an example of the member and method you can use to prevent that from happening:
private Form frm;
private void button1_Clicked(object sender, EventArgs e)
{
if (frm != null)
{
frm.Close();
frm.Dispose();
}
frm = new Form1();
frm.Show();
}
private void button2_Clicked(object sender, EventArgs e)
{
if (frm != null)
{
frm.Close();
frm.Dispose();
}
frm = new Form2();
frm.Show();
}
You can read up about mutual exclusion http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx
It is a general solution to make sure you only have 1 thing (thread, process, form, whatever) of something at the same time. You can even use it inter application.
An example is shown here: http://www.dotnetperls.com/mutex
You can create multiple mutexes, one for each form. Or one for a set of forms, in what ever combination suits you.
Example Scenario:
Form1 creates a mutex with name X
Form2 is being loaded checks whether mutex X is created, if so it closes itself.
Of course you will need to make sure the mutex is Disposed / released when the creator (Form1 in this example) closes, to allow other forms to show.
You can use some flag for this purpose OK, like this:
bool formOpened;
private void buttons_Click(object sender, EventArgs e){
if(!formOpened){
//Show your form
//..............
formOpened = true;
}
}
//This is the FormClosed event handler used for all your child forms
private void formsClosed(object sender, FormClosedEventArgs e){
formOpened = false;
}
At least this is a simple solution which works.
In general case, you need a int variable to count the opened forms, like this:
int openedForms = 0;
//suppose we allow maximum 3 forms opened at a time.
private void buttons_Click(object sender, EventArgs e){
if(openedForms < 3){
//Show your form
//..............
openedForms++;
}
}
private void formsClosed(object sender, FormClosedEventArgs e){
openedForms--;
}
Does this mean while you have Form1 open, you want to still be able to open a Form2 and 3 and etc?
It you don't want that, you can use the form1Instance.SHowDialog() instead of Show()...
But that generally means you can't access the parent form while form1 is open...
But King King's anwser might be more useable to you.

Detect when a form has been closed c#

I have a WinForm that I create that shows a prompt with a button. This is a custom WinForm view, as a message box dialog was not sufficient.
I have a background worker started and running. I also want to exit the while(aBackgroundWorker.IsBusy) loop if the button on myForm was clicked.
//MyProgram.cs
using(CustomForm myForm = new CustomForm())
{
myForm.Show(theFormOwner);
myForm.Refresh();
while(aBackgroundWorker.IsBusy)
{
Thread.Sleep(1);
Application.DoEvents();
}
}
Right now, in the CustomForm the Button_clicked event, I have
//CustomForm.cs
private void theButton_Click(object sender, EventArgs e)
{
this.Close();
}
Do I need to add more code to the CustomForm class, or the location where I declare and initialize the form in order to be able to detect a closure?
To detect when the form is actually closed, you need to hook the FormClosed event:
this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// Do something
}
Alternatively:
using(CustomForm myForm = new CustomForm())
{
myForm.FormClosed += new FormClosedEventHandler(MyForm_FormClosed);
...
}
void MyForm_FormClosed(object sender, FormClosedEventArgs e)
{
// Do something
}
You might be going overkill. To show a form like a dialog window and wait for it to exit before returning control back to the calling form, just use:
mySubForm.ShowDialog();
This will "block" the main form until the child is closed.
Make sure your background worker supports cancellation and as others have pointed out use the form closed event handler. This code should point you in the right direction:
using(CustomForm myForm = new CustomForm())
{
myForm.FormClosed += new FormClosedEventHandler(ChildFormClosed);
myForm.Show(theFormOwner);
myForm.Refresh();
while(aBackgroundWorker.IsBusy)
{
Thread.Sleep(1);
Application.DoEvents();
}
}
void ChildFormClosed(object sender, FormClosedEventArgs e)
{
aBackgroundWorker.CancelAsync();
}
Handle the FormClosing event of the form to be notified when the form is closing, so you can perform any cleanup.
You should be able to hook into the FormClosing and FormClosed events.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosed.aspx
Closing is before it's closed.
Closed is after it's closed.
A couple things...
First, it appears that loop is there in order to prevent execution form proceeding while the dialog is open. If that is the case, change you .Show(parent) to .ShowDialog(parent). That will also take care of the rest of your question.
Note that this.Hide(); is not the same as this.Close(); in the actual dialog your overriding the closed event

Categories

Resources