Closing One Form From Another Form? - c#

I have a little application that creates alerts whenever a change to a database is made.
I have a few options in the alert form that pops up.
One of the options opens another form (a child form) asking the user for further information.
When the child form gets the necessary information from the user, I want it to close as well as the parent form. So far, I only know how to close the child form, but not the parent form.
Parent form > Opens child form
Child gathers information > User clicks ok in child > child closes, parent closes
^this is what I want
I just don't have the brain power to think about how to communicate across forms to accomplish closing the parent form.
Any help would be much appreciated. Actually, it would be super appreciated. If I could learn how to make my forms communicate with each other, I could really do a lot of damage (in a good way 8D ).

In the parent form, you can do something like this:
ChildForm f = new ChildForm();
f.FormClosed += (o,e) => this.Close();
f.Show();

Try this in the parent form:
using (var childForm = new ChildForm())
{
if (childForm.ShowDialog() == DialogResult.OK)
{
Close();
}
}
Your child form should return a DialogResult by clicking buttons (OK or Cancel) and/or setting the AcceptButton and CancelButton properties in the designer.

Related

How to edit the parent Form when a child Form is active?

When I open a child Form, I need the parent Form to remain accessible.
For example, I could type in a text field.
You should use user controls for this type of functionality.
by using user controls you can use single form with multiple user controls at a time.
to know how user control works:
watch this video
OR
by using show(), Hide(), BringToFront() and SendToBack() you can do but it will add complexity to your code.
You can open it by Show, but maybe set original form as owner, so that it does not move to background.
var f2 = new Form2();
f2.Owner = this;
f2.Show();

c# set focus on multiple child forms

I have a main form and then open one childdialog (nr 1) and on that I open an other childdialog (nr 2).
When I then open up that main form from another application the focus is set on the last child (nr 2), when I press enter the focus is set on the main form, I want the focus to go on child nr 1.
To open up the main form I use Activate();
Then in OwnedForms I have an array of children.
Activate();
if(OwnedForms.Any())
{
OwnedForms.Last().Focus();
}
When I choose to close that form that has focus, the focus will go to the main form instead of the next child (last -1) in the OwnedForms array.
Tried bringtofront and sendtoback without any success.
Make sure that the form's parent is set.
OwnedForms.Last().Parent = this;
Also you may want to look into .Show() vs .ShowDialog() on the forms.
It seems like you might prefer .ShowDialog() in your case if you are not already doing so.

How to show new form without disabling the parent form?

I have shown a new form in button click on parent form like below,
Here the background parent form gets disabled when a new child form is activated.
Is there any available options to show the child form without disabling the parent form?
Regards,
The Show function shows the form in a non modal form. This means that you can click on the parent form.
ShowDialog shows the form modally, meaning you cannot go to the parent form
Application.Run() runs the main parent form, and makes that form the main form. Application.Run() is usually found in main.
If it is fully disabled (no interaction possible), you are using .ShowDialog() on the child form instead of .Show(). If you use .Show() you will be able to use both forms
Example:
ChildForm childForm = new ChildForm();
childForm.Show();
after you open the new form and call this.Activate(); it will refocus on the parent window, but this will cause it to loose focus for a fraction of a second

Two winforms one modal dialog situation

I have two open winforms, say that winform1 gets a modal dialog, this means that all forms(winform1 and winform2) will be "disabled". If we minimize all forms and then bring up winform1, then the modal dialog will be shown above it. If we again minimize all the forms but this time brings up winform2, it will look like the finform2 is ready to be used while its really disabled like winform1.
What I need is to clearly show that the modal dialog needs to be handled before using winform2 again.
Is there anything built in to handle this or am I on my own here?
In your winform2.Activated event handler, call this:
static void FocusModalForm()
{
foreach (Form form in Application.OpenForms)
if (form.Modal)
{
form.WindowState = FormWindowState.Normal;
form.BringToFront();
}
}
e.g.
Form f2 = new Form();
f2.Activated += (_, __) => FocusModalForm();
f2.Show();
You may need to do the same thing for winform1's Activated event. It depends how winform2 gets created. Just try it and if you find that winform1 (or any other nonmodal form) is still able to get in front of the modal form, just call FocusModalForm() from its Activated event.
I tried this in Windows 7. I tried hiding all windows (click the Show Desktop button on the taskbar) and then selecting form2 directly from the taskbar, and I also tried just selecting form2 from the taskbar without hiding all windows. Form3 always stayed on top.
I have a similiar app (vb.net) where win1 calls win2 & win2 displays win3 and it works as you would like but wins 2 & 3 are both modal. I don't know if that is why it works or not. Perhaps that is an option for you?
If you do this:
var winform2 = new Winform2();
winform2.Show(winform1);
Then winform2 will always be shown above winform1, but it won't be modal. May be this can help you.

How to prevent MDI main form closing from MDI Child

I have a MDI main form. On it I host a form, and I want it to show a message box before it closes (asking the user whether to save changes).
So far so good, however I have discovered that closing the MDI main form does not raise a MDI child FormClosing event. I figured I will just call MdiChild.Close() in the MDI main's FormClosing event (which does get raised). This seams to work, however it does causes a problem...
In the messagebox that I show, I offer the user to save changes, not to save changes and cancel closing. Normally this works fine, however I can't seem to find a way to cancel MDI main's FormClosing event. Is there a elegant way of doing this?
EDIT: I solved this by throwing an exception (when user decides to cancel the closing procedure) which is caught in MDI main's FormClosing event. In this way I know when I have to cancel the MDI main's FormClosing event and this seams to work fine ... However I just can't believe that this "hax" is the only way of doing this. Surely there is a better way?
I figure that you cancel the close on the childform when the user votes to cancel the close?
In that case I'd go with this Main form close
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
foreach (Form frm in this.MdiChildren)
{
frm.Close();
}
}
e.Cancel = (this.MdiChildren.Length > 0);
}
I'd suggest that instead of calling Close on the childforms you could create a method like ReadyToClose in the child forms and then the main form loops through and calls that for each of the child forms and it'll ask the question to the user and do the saving if needed and finally it'll return true if ok to continue.
And if all of the child forms "vote" for a close, then you close it all down, otherwise you close nothing.
When closing the MDI main form, all child Close events are called first so, when calling frm.Close() on the foreach loop, Close events for the child are called again (I don't know why if they should be already closed).
ho1 suggestion worked pretty well for me. Here is my modified foreach loop (ClosableMDIChildForm is an interface which contains the IsOkToClose() method):
foreach (ClosableMDIChildForm cmdif in this.MdiChildren)
{
if (!cmdif.IsOkToClose())
{
e.Cancel = true;
((Form)mdifc).Focus();
break;
}
}
Obviously, this.MdiChildren forms must implement ClosableMDIChildForm interface. The logic to decide if it's OK to close the window goes in the implementation of IsOkToClose().

Categories