Как избежать нескольких дочерних форм, показанных в формах Mdiparent C# Win

Я хочу, чтобы моя дочерняя форма не появлялась много раз, когда пользователь пытается открыть дочернюю форму, которая уже открыта в MDIParent. Один из способов избежать этого-отключить контроллер (в моем случае кнопка), но я дал горячую клавишу ( Ctrl+L) для этой функции, а также. Поэтому, если пользователь вводит Ctrl+L, открывается одна и та же дочерняя форма, и я вижу, что две дочерние формы находятся в MDI.

private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        frmWebLeads formWeblead = new frmWebLeads();
        formWeblead.MdiParent = this;
        formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized;
        formWeblead.Show();

    }

Я хочу избежать этого. Как я могу это сделать? enter image description here

на изображении вы можете видеть, что имя дочерней формы Онлайн-Приводит открывается дважды, как пользователь открыл первый раз с помощью меню (ведет) и второй раз с помощью клавиши быстрого доступа. Я не хочу, чтобы это произошло. Если форма уже открыта, следует избегать открытия другой такой же формы ... Как это сделать?

15 ответов


то, как я обычно это делаю, если я должен иметь только один открытый, что-то вроде:

//class member for the only formWeblead
frmWebLeads formWebLead = null;

private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (formWebLead == null)
    {
        formWeblead = new frmWebLeads();
        formWeblead.MdiParent = this;
    }

    formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized;
    formWeblead.Show();
}

установите это в своей форме main() function

    InitializeComponent();
     this.WindowState = FormWindowState.Maximized;
     this.ShowInTaskbar = true;

 from_login login = new from_login();
                login.MdiParent=this;
                login.Show();
                pmsnrr.pmsmain = this;  

и это код, который идет внутри вашего события slick Strip меню

if (this.ActiveMdiChild != null)
            this.ActiveMdiChild.Close();
            frm_companymaster company = new frm_companymaster();
            company.MdiParent = this;
            company.WindowState = FormWindowState.Normal;
            company.Show();

private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
{
    formWeblead formWeblead = null;
    if ((formWeblead = IsFormAlreadyOpen(typeof(frmWebLeads)) == null)
    {
        formWeblead = new frmWebLeads();
        formWeblead.MdiParent = this;
        formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized;
        formWeblead.Show();
    }
}

public static Form IsFormAlreadyOpen(Type FormType)
{
   foreach (Form OpenForm in Application.OpenForms)
   {
      if (OpenForm.GetType() == FormType)
         return OpenForm;
   }

   return null;
}

Я лично предпочитаю обычную реализацию:

private void ShowOrActivateForm<T>() where T : Form
        {
            var k = MdiChildren.Where(c => c.GetType() == typeof(T)).FirstOrDefault();
            if (k == null) 
            {                    

                k = (Form)Activator.CreateInstance(typeof(T));
                k.MdiParent = this;
                k.Show();
            }
            else
            {
                k.Activate();                
            }            
        }

тогда вы можете просто использовать его следующим образом:

ShowOrActivateForm<myForm>();

где myForm-тип формы, которую вы хотите создать


    frmWebLeads formWeblead;

    bool isformWebleadOpen =false;

    private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if(isformWebleadOpen == false)
      {
       formWeblead = new frmWebLeads();
       isformWebleadOpen =true;
       formWeblead.Closed += formWeblead_Closed;
       formWeblead.Show();
      }
   }

   void formWeblead_Closed(object sender, EventArgs e)
   {
     isformWebleadOpen = false;
   }

время Кулаков при открытии формы из меню переменная frmRep равна null

frmReportes frmRep = null

...поэтому я добавляю еще одно "если" внутри первого "если" для проверки моей формы видно, потому что у меня есть другие формы, то если его не видно, я делаю экземпляр и показываю форму, но если видно, я просто использую Activate()

    private void rToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (frmRep != null)
        {
            if (frmRep.Visible == false)
            {
                frmRep = new frmReportes();
                frmRep.MdiParent = this; frmRep.Show();
            }
            else
            {                    
                frmRep.Activate();
                return;
            }
        }
        else
        {
            frmRep = new frmReportes();
            frmRep.MdiParent = this; 
            frmRep.Show();
        }            
    }

самый простой способ-сохранить ссылку на дочернюю форму и создать новую, если она еще не существует. Что-то вроде этого:--2-->

class ParentForm : Form { 
    frmWebLeads formWeblead = null;

    //...

    private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if(formWeblead != null) return;
        formWeblead = new frmWebLeads();
        formWeblead.MdiParent = this;
        formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized;
        formWeblead.Show();

    }

}

Вам также нужен код, чтобы установить formWeblead в null при его закрытии, но я уверен, что вы можете понять эту часть:)


// Implementation of the below class in your MDI Parent
private void openToolStripMenuItem_Click(object sender, EventArgs e) {
            if (SingletonForm.Exists) {
                return;
            } else {
                m_openToolStripMenuItem.Enabled = false;

                SingletonForm form = new SingletonForm();
                form.FormClosed += new FormClosedEventHandler(
                    delegate(object _sender, FormClosedEventArgs _e) {
                        m_openToolStripMenuItem.Enabled = true;
                    });
                form.MdiParent = this;              
                form.Show();
            }
        }


// SingletonForm Class
    using ...
    using System.Threading;

    namespace SingletonForm {

        public partial class SingletonForm : Form, IDisposable {
            static private readonly string m_mutexName = "SingletonForm.SingletonForm";
            private Mutex m_mutex;
            private bool m_disposed;

            public SingletonForm() {
                m_disposed = false;

                // Check to see if there is already a running instance...
                bool owned;
                m_mutex = new Mutex(true, m_mutexName, out owned);
                if (!owned) {
                    // Already running, get out...
                    Close();
                    return;
                }

                InitializeComponent();
            }

            ~SingletonForm() {
                Dispose(false);
            }

            static public bool Exists {
                get {
                    bool owned;
                    using (new Mutex(false, m_mutexName, out owned)) {
                        return !owned;
                    }
                }
            }

            // IDisposable Members
            // --------------------------------------------------------------------------
            #region IDisposable Members
            new public void Dispose() {
                Dispose(true);

                // Use SupressFinalize in case a subclass of this type implements a finalizer.
                GC.SuppressFinalize(this);
            }
            #endregion  // IDisposable Members

            /// <summary>
            /// Note: Comment out the Dispose(bool disposing) implementation in your
            /// SingletonForm.Designer.cs
            /// </summary>
            /// <param name="disposing">true if we are disposing.</param>
            protected override void Dispose(bool disposing) {
                if (disposing && (components != null)) {
                    components.Dispose();
                }

                base.Dispose(disposing);

                // If you need thread safety, use a lock around these 
                // operations, as well as in your methods that use the resource.
                if (!m_disposed) {
                    if (disposing) {
                        // Code to dispose the managed resources held by the class here...
                        if (m_mutex != null) {
                            m_mutex.Dispose();
                            m_mutex = null;
                        }
                    }

                    // Indicate that the instance has been disposed.
                    m_disposed = true;
                }
            }
        };
    };

было бы неплохо использовать вместо этого семафоры, чтобы позволить существовать 1-n экземпляров.


вот "метод", который я создал для вызова открыть только одну форму, когда u нажмите на меню в MDIParent. Надеюсь, этот "метод" поможет вам!

Использование: На Даже ToolStripMenuItems.

Form1 frm1 = new Form1();
CheckActiveChildForm(frm1,"myForm");

//myForm is the Text of Form1
private void CheckActiveChildForm(Form FormControl, string FormExists)
{
    int h = 0;
    if (MdiChildren.Count() == 0)
    {
        //Form2 childF = new Form2();
        FormControl.MdiParent = this;
        FormControl.Show();
    }

    if (MdiChildren.Count() > 0)
    {
        for (int i = 0; i < MdiChildren.Count(); i++)
        {
            if (MdiChildren.ElementAt(i).Text == FormExists)
            {
                h = 1;
            }
        }
    }

    if (h == 0)
    {
        FormControl.MdiParent = this;
        FormControl.Show();
    }
}

вы можете проверить текущие открытые формы, чтобы достичь этого:

if (Application.OpenForms.Count == 1) {
    ReportProductDetails Report9 = new ReportProductDetails();
    Report9.MdiParent = this;
    Report9.Show();
    Report9.Activate();
}
else {
    MessageBox.Show("Sorry!Close the All the Exist Form,Before open this Form", "Information", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Я использую это решение, с небольшую хитрость

frmWebLeads formWebLead = null;

private void leadsToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (formWebLead == null || formWebLead.isAccessible == false)
        {
            formWeblead = new frmWebLeads();
            formWeblead.MdiParent = this;
        }

        formWeblead.WindowState = System.Windows.Forms.FormWindowState.Maximized;
        formWeblead.Show();
    }

    private void mnuMyForm_Click(object sender, EventArgs e) // click to open MyForm
    {
        foreach (Form item in this.MdiChildren) // check all opened forms
        {
            if (item.Name == "MyFormName") // check by form name if it's opened
            {
                item.BringToFront(); // bring it front
                return; //exit
            }
        }

        // if MyForm is not opened
        // you know what it is
        MyForm frm = new MyForm();
        frm.MdiParent = this;
        frm.Show();
    }

код, который предотвращает одну и ту же дочернюю форму в форме MDI

private void materialToolStripMenuItem_Click(object sender, EventArgs e)
{
  frmMaterial newMDIChild = new frmMaterial();
  bool opened = false;
  foreach (Form OpenForm in Application.OpenForms)
  {
    if (OpenForm.GetType() == typeof(frmMaterial))
    {
      OpenForm.Activate();//to bring the activated form to the front
      opened = true;
    }
  }
  if (opened==false)
  {
    // Set the Parent Form of the Child window.
    newMDIChild.MdiParent = this;
    //newMDIChild.WindowState = System.Windows.Forms.FormWindowState.Maximized;
    // Display the new form.
    newMDIChild.Show();
  }
}

простейшие способы предотвращения множественного экземпляра ребенка:

 private void Showforms(Form frm)
 {
   if (this.ActiveMdiChild==null)
   {
      frm.MdiParent = this;               
      frm.Show();
   }
 }

тогда назовите это так:

Form1 frm = new Form1();
Showforms(frm);

в simpleist способы предотвращения несколькими экземплярами детей

private void Showforms(Form frm)
{
    if (this.ActiveMdiChild==null)
    {
        frm.MdiParent = this;
        frm.Show();
    }  
}