Roy Osherove

View Original

Problem & Solution: Allow only one instance of any MDI child form in your MDI application

One of the things I needed to do at an MDI application I was involved with was the ability to only load a specific form once, and make sure it does not load again. That form could not be modal, but could only have one instance running inside the MDI parent.  I came up with a rather elegant solution, if I do say so myself :)

(Of course what usually happens when I come up with an “elegant” solution is that someone shows me a simple property on the form that says something like "AllowOneInstanceOnly" which does exactly what I did here. )

How to call this class:

In your MDI form, simply write this:

 

MdiFormLoader.LoadFormType(typeof(CustomerDetailsForm), this);


using System;

using System.Windows.Forms;

using System.Collections.Specialized;

 

namespace UI.Utilities

{

      public class MdiFormLoader

      {

            private static HybridDictionary m_InitializedForms = new HybridDictionary();

 

            public static void LoadFormType(Type formType, Form mdiParentForm)

            {

                  if (IsAlreadyLoaded(formType))

                  {

                        return;

                  }

                 

                  FlagAsLoaded(formType);

                  Form frm = (Form)Activator.CreateInstance(formType);

                  frm.MdiParent = mdiParentForm;

                  frm.Closed += new EventHandler(FormClosed);

                  frm.Show();

            }

            private static void FlagAsLoaded(Type formType)

            {

                  m_InitializedForms[formType.Name] = true;

            }

 

            private static void FlagAsNotLoaded(Type formType)

            {

                  m_InitializedForms[formType.Name] = false;

            }

 

            private static bool IsAlreadyLoaded(Type formType)

            {

                  return ((m_InitializedForms[formType.Name] != null) &&

                        (bool)m_InitializedForms[formType.Name] == true);

            }

 

            private static void FormClosed(object sender, EventArgs e)

            {

                  Form closingForm = (Form)sender;

                  closingForm.Closed -= new EventHandler(FormClosed);

                  FlagAsNotLoaded(sender.GetType());

            }

      }

}