12
votes

I am using this function to close existing form and open a new form.

If there is no exixting form, it throws error.

Error :

Target : System.Object MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)

Message : Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

Stack : at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)

SO need to check for any form open before closing the form to avoid the error. How?

    static public void NewMainForm(Form main, bool ClosePreviousMain)
    {
            if (main != null)
            {
                Global.ActiveForm = main.Text;
                if (ClosePreviousMain & MyContext.curMain != null)
                {
                    MyContext.curMain.FormClosed -= new FormClosedEventHandler(main_FormClosed);
                    //Need to check for any form active and then close the form.
                    MyContext.curMain.Invoke(new Action(MyContext.curMain.Dispose));
                }
                MyContext.curMain = main;
                MyContext.curMain.FormClosed += new FormClosedEventHandler(main_FormClosed);
                MyContext.curMain.ShowDialog();
            }
    }
5

5 Answers

28
votes
11
votes
if (ApplicationFormStatus.CheckIfFormIsOpen("FormName")) 
{
// It means it exists, so close the form
}

 public bool CheckIfFormIsOpen(string formname)
        {

            //FormCollection fc = Application.OpenForms;
            //foreach (Form frm in fc)
            //{
            //    if (frm.Name == formname)
            //    {
            //        return true;
            //    }
            //}
            //return false;

            bool formOpen= Application.OpenForms.Cast<Form>().Any(form => form.Name == formname);

            return formOpen;
        }

I have pasted the two methods one simple one and the second one is the LINQ.

4
votes

If you know the name of the form you can as well do like this :

var frm = Application.OpenForms.Cast<Form>().Where(x => x.Name == "MyForm").FirstOrDefault();
if (null != frm)
{
    frm.Close();
    frm = null;
}
2
votes

this part of code searches for existing instance of a form if exists just shows it , and if not creates an instance of it

       `foreach (Form form in Application.OpenForms)
        {
            if (form.GetType() == typeof(myMainform))
            {
                form.Activate();
                form.Show();
                this.Close();
                return;
            }
        }

        myMainform m = new myMainform();
        m.Show();`
0
votes

I might be late here but just in case someone needs this. If Application.OpenForms is missing on your side, that's because you have to use System.Windows.Forms.Application.OpenForms

For example:

FormCollection fc = System.Windows.Forms.Application.OpenForms;

The fc object contains properties as: Count and InnerList(very useful)

Hope it helps, even if it is 2021, I thought that someone would need this information ( I haven't seen it anywhere when I searched for it)