Close all forms besides 'switch board' - c#

I need to be able to close a form and have it close all other forms besides the switch board. I tried using this code but it also closes the frmSwitch even though I attempted to code it to close all but that. Where did I go wrong? I am supposed to use the actual name of the form correct?
Form[] forms = Application.OpenForms.Cast<Form>().ToArray();
foreach (Form thisForm in forms)
{
if (thisForm.Name != "frmSwitch") thisForm.Close();
}

You need to check if thisForm is frmSwitch, and then close the rest.
foreach (Form thisForm in Application.OpenForms)
{
if (!(thisForm is frmSwitch))
thisForm.Close();
}
You also don't have to use Cast<Form> and ToArray, you can enumerate FormCollection

This will work assuming you are closing from your "main form"
var list = Application.OpenForms.Cast<Form>().ToArray();
foreach (Form item in list)
{
if (item.Equals(this)) continue;
item.Close();
}

Related

Doesn't work in Runtime form child form closing method

I'm trying to create a method to close all child forms in windows application C#.
There are no errors but it doesn't work in runtime!
private void closechildform(Form f)
{
foreach (Form frm in this.MdiChildren)
{
frm.SendToBack();
frm.Hide();
return;
}
}
You should move the return to outside the foreach loop. Because in your existing code it will return after first iteration.
FYI: If the method is void then there’s no need of return inside the method.

Closing a form when other form is opening

The current problem is that the "mainScreen" shows up, but immediately closes, I have no idea why. This is the piece of code that handles the close and opening of the new form.
Edit: .this refers to Login.cs (sorry)
if(templogin == true && permission.Equals("1"))
{
mainScreen.IsAdmin();
this.Close();
mainScreen.ShowDialog();
}
I think, you should not close the application(as login form seems main form while you started the application) before another form run:
Do like this :
if(templogin == true && permission.Equals("1"))
{
this.Hide();
mainScreen.IsAdmin();
mainScreen.ShowDialog();
this.Close();
}
If you want to run 2 forms (switching from one to another), then you should do it in Main
Instead of
Application.Run(new StartupForm());
you'll have to use
var startup = new StartupForm();
startup.ShowDialog();
if(somecondition) // when StartupForm is closed and return something (or property is set, etc)
{
var main = new MainScreen();
main.ShowDialog();
}
You don't need Application.Run at all when using ShowDialog.

WPF Close all child window except active child window and main window

I have C# WinForms code as follows to close all child forms when I open a new child form:
private void CloseAllActiveForms(Form[] MdiChildren)
{
Form[] childArray = MdiChildren;
foreach (Form childform in childArray)
{
childform.Close();
}
}
How can I use in WPF windows?
I tried the below code, but it will close all windows including the Parent and the Active window.
private void CloseAllWindows()
{
for (int intCounter = App.Current.Windows.Count - 1; intCounter >= 0; intCounter--)
{
Application.Current.Windows[intCounter].Close();
}
}
Thanks.
As far as I know, MDI support for WPF is limited, so try using the Tag attribute when you create your pseudo-child windows:
Window child = new Window();
child.Tag = "mdi_child";
Then, in your loop, modify it like this:
foreach (Window win in App.Current.Windows)
{
if (!win.IsFocused && win.Tag.ToString() == "mdi_child")
{
win.Close();
}
}
Note that for the above solution to work, ALL windows must have a Tag attribute, or else an Exception will be thrown at win.Tag.ToString().
Here is a method I use in WPF to close all child windows of my program, this code goes in the main window.cs file, but you could modify if(item!=this) to check for a particular window:
foreach(Window item in App.Current.Windows)
{
if(item!=this)
item.Close();
}
No faffing around with sub-classes or more lists (especially as the code already has a list of windows associated with it.)
If you wanted to selectively close windows then you could always modify the if statement to use a variable on the window class or check one of the pre-existing variables (such as a the class of the parent window) on the base window class.

Form.Close() doesn't close window immediately

I need to be sure that all forms will be closed if I user somehow close the main form. So I decided to hide Close() function and I wrote something like this
public new bool Close()
{
List<Form> formsList = new List<Form>(Application.OpenForms.Count);
foreach (var form in Application.OpenForms)
formsList.Add((Form)form);
formsList.Reverse();
foreach (var form in formsList)
{
if (form.IsDisposed) continue;
Invoke(new GenericEventHandler(() => { form.Close(); }));
}
return Application.OpenForms.Count == 0;
}
So if all forms are closed successfully I return true and thanks to this I know that user can be logged out from application.
However it seems that form.Close() function is not fired immediately. After calling form.Close() formclosed event is not fired immediately as well as collection Application.OpenForms is not modified. The amount of opened forms is noted changed.
What could be a reason?
Why dont you just use
Application.Exit();
If the main form is created in the standard way in WinForms via Application.Run(new MainForm()); then when it closes, the application will exit, closing all other forms. So I don't think you need to worry about manually closing all child forms.
Well, if the user closes the main form, then upon closing it your application will definitely exit, since your form is responsible for keeping the application alive when it was passed to Application.Run().
Now, if you want to close your app when a form is closed, in that form you do this:
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
Application.Exit();
}
In general I suggest not to use new keyword to any members of Control and/or Form class. If you need your own method use your own name of it.
In your code you don't really need to use Invoke when closing child forms.
If you need to be sure that all your child Forms are closed before you actually execute logic related to MainForm.Close you may subscribe to MainForm.FormClosing event with handler similar to follwing:
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bool allChildFormsClosed = !closeAllChildForms();
if(!allChildFormsClosed)
{
e.Cancel = true;
MessageBox.Show("Failed to close one or more child forms.");
// better add some yes|no dialog to force exit if necessary
}
}
You may implement closeAllChildForms in a similar way as you did above - just: remove the formsList.Reverse(); and the 'Invoke..' - just call Close directly and update: if (this == form || form.IsDisposed) continue;
If for some reason, Application.Exit isn't cutting it for you, you could try this code (put it in the form's FormClosing event):
while (Application.OpenForms.Count > 1)
{
Form form = Application.OpenForms[1];
form.Close();
while (!form.IsDisposed) Application.DoEvents();
}
or if you want it to time out if it can't close all the forms after a while,
while (Application.OpenForms.Count > 1)
{
Form form = Application.OpenForms[1];
form.Close();
DateTime StartTime = DateTime.Now;
while (!form.IsDisposed && (StartTime - DateTime.Now).TotalMilliseconds < 1000)
Application.DoEvents(); //1-second timeout here
if (!form.IsDisposed) //if it's still not closed
{
//send a message to the user that the application can't exit right now
mbox("some forms are still open or whatever");
e.Cancel = true;
return;
}
}

close the form from mdi parent when i click to open any other form

i have a mdi form and there is lot of other form linked with the menu strip. when i click any other menu item then there should be close previous open form inside the mdi parent form.
Here is a more succinct, modern, and surgical way to close all MdiChild forms:
static void CloseAllMdiChildForms()
{
foreach (var form in Application.OpenForms.Cast<Form>().Where(f => f.IsMdiChild).ToArray()) // ToArray necessary to build a snapshot
form.Close();
}
However, it sounds like what you want is to have only one child form open at any given time. If that is the case, MDI is not the right tool for the job. You can build UserControls and swap them into and out of your main application form instead.
Call this method when you want to open a new form:
private void CloseAllForms()
{
Form[] formToClose = null;
int i = 1;
foreach (Form form in Application.OpenForms)
{
if (form != this) //this is form1
{
Array.Resize(ref formToClose, i);
formToClose[i - 1] = form;
i++;
}
}
if (formToClose != null)
for (int j = 0; j < formToClose.Length; j++)
formToClose[j].Dispose();
}
Mitja
This is best one:
static void CloseAllMdiChildForms()
{
foreach (var form in Application.OpenForms.Cast<Form>().Where(f => f.IsMdiChild).ToArray()) // The ToArray is necessary to build a snapshot
form.Close();
}

Categories