2011-07-12 35 views
8

Quiero evitar que mi formulario hijo aparezca muchas veces cuando un usuario intenta abrir el formulario secundario que ya está abierto en MDIParent. Una forma de evitar esto es desactivando el Controlador (en mi caso, BUTTON), pero he dado una tecla de acceso directo (Ctrl + L) para esta función también. Por lo tanto, si el usuario escribe Ctrl + L, se abre el mismo formulario secundario y puedo ver que hay dos formularios secundarios en MDI.Cómo evitar el formulario Multiple Child mostrado en MDIParent C# Win Forms

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

    } 

Quiero evitar esto. ¿Cómo puedo hacer esto? enter image description here

En la imagen se puede ver que una forma de niño Nombre línea Conductores de se abre dos veces como el usuario abre por primera vez utilizando los menús (derivaciones) y la segunda vez con la tecla de acceso directo. No quiero que esto suceda. Si el formulario ya está abierto, debería evitar abrir otro formulario ... ¿Cómo hacer esto?

Respuesta

4

la forma en que suele hacer si soy sólo supone que tiene una abierta es algo así como:

//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(); 
} 
0

La forma más fácil es mantener una referencia al formulario secundario, y sólo generar una nueva si no existe ya Algo como esto:

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(); 

    } 

} 

También necesita código para establecer formWeblead en nulo cuando se cierra, pero estoy seguro de que puede entender esa parte :)

+0

@ Mike Caron gracias por su Código. La última parte la dejaste para mí creando cierta confusión, tengo dudas de que la forma declarada Weblead en MDIParent y estoy pensando en configurar formWeblead = null usando frmWebLoad dejando Evento usando acceso de Hijos a padres, ¿está bien? ??? o hay algún mejor método disponible – panindra

+1

No creo que use el evento Leaving, ya que eso es algo que se enfoca. En cambio, usa el evento Closing del formulario secundario, que se activa cuando lo cierras. –

+0

@Mike Esto deja TODO con respecto al elemento del menú que llama al evento click; Me gusta desactivar el elemento del menú que creó el formulario para evitar confusiones para el usuario, p. "Hago clic en 'abrir' y no pasa nada". – gangelo

3
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; 
} 
+0

Lo siento, pero no tengo el mismo problema. Estoy corriendo .NET 3.5 en VS 2008. Puedo cerrar y abrir solo un formulario repetidamente. – Joe

+0

estoy usando .net 3.5 y VS 2010 Ultimate, Windows Xp ..es este error de cousing – panindra

0
// 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; 
       } 
      } 
     }; 
    }; 

Habría Ha sido agradable usar semáforos en su lugar para permitir que existan 1-n instancias.

0

Aquí está el "Método" que creé para Llamar al abrir un solo formulario cuando haces clic en Menú en MDIParent. ¡Espero que este "Método" pueda ayudarte!

Uso: En Even 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(); 
    } 
} 
+0

¿Por qué downvote? –

4

Esta función debe ajustarse en su forma principal()

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

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

y este es el código de la pasa dentro de su franja menú de eventos mancha de

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

Usted puede comprobar las formas abiertas actuales a lograr eso:

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); 
} 
0

Yo uso esta solución, con un pequeño truco

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(); 
    } 
1
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; 
    } 
2

yo personalmente prefiero una implementación genérica:

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();     
      }    
     } 

a continuación, puedes utilizar de esta manera:

ShowOrActivateForm<myForm>(); 

Dónde myForm es el TIPO del formulario que desea crear

+0

Me gusta este enfoque. Es mucho más escalable que crear campos vacíos para cada niño. +1 para genéricos. Me interesaría saber si hay alguna sobrecarga adicional notable para el uso de la reflexión; aunque en un nivel muy alto. – Apache

+1

Me imagino que cualquier sobrecarga adicional sería insignificante. Solo se ejecuta cuando intentas abrir un formulario, así que a menos que abres toneladas de formularios a la vez, no puedo imaginar que tenga un impacto en el rendimiento de tu aplicación o en tu experiencia como usuario. –

+0

Eso está bien. Supongo que en una aplicación escalable, usarías tu contenedor IoC de todos modos, en lugar de depender del 'Activador'. He usado este método con RadDock ahora, para realizar un seguimiento de MDI Children y Tool Windows. He sacado 'Show()' y 'Activate()' y devolví el formulario sin procesar como tipo 'T', para que pueda ser acoplado donde sea necesario. – Apache

0

El código que impide que la misma forma de niño en un formulario 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(); 
    } 
} 
0
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(); 
    } 
1
tiempo

puños cuando se abre el formulario desde el menú, la variable frmRep es nulo

frmReportes frmRep = null 

... así Agrego otro "si" dentro del primer "si" para validar que mi formulario es visible, porque tengo otros formularios, entonces, si no está visible hago una instancia y muestro el formulario, pero si está visible solo uso 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(); 
     }    
    } 
0

las formas simpleist de la prevención de varias instancias del niño

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

Las formas más sencillas de prevención de múltiples instancias del niño:

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

A continuación, llame así:

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