Forms en paneles, adiós a los formularios MDI

ACTUALIZACIÓN IMPORTANTE!: En uno de los comentarios un lector me hizo caer en cuenta de un grave error, el código, como estaba, generaba siempre una nueva instancia del formulario y solo removíamos la referencia del contenedor… lo que significaba un uso excesivo de memoria. El articulo fue actualizado explicando está ultima implementación. Cualquier sugerencia adicional es siempre bienvenida.

Cuando necesitamos trabajar múltiples “vistas” dentro de nuestros formularios por lo general recurrimos al control TabControl, pero cuando necesitamos ya una funcionalidad es muy compleja o simplemente queremos separar estas funcionalidades en interfaces diferentes e integrarlas en un solo formulario, recurrimos a los formularios MDI, en estos podemos trabajar con formularios padres (contenedor) y sus formularios hijos (contenidos), personalmente no tengo nada en contra de estos, pero me parecen un tanto tediosos de trabajar y algo estrictos en su personalización.

Es por eso que en una ocasión, cuando necesitaba hacer un proyecto de ese estilo, me decidí por integrar otro método para acoplar formularios hijos en uno padre SIN QUE ESTE FUERA UN MDI CONTAINER, ni trabajar con los TabControls. Al ver la sección de contenedores en el ToolBox de Visual Studio vi el Panel, un control tan simple pero tan potente que a la final sería la mejor solución a mi problema, aquí les dejo como lo hice.

Una vez aclarados estos antecedentes, manos al teclado, lo primero que vamos a hacer es crear un proyecto de tipo Windows Forms, a este le vamos a agregar tres Forms (Padre, Hijo1, Hijo2):

Form Padre e hijos

Al formulario Padre, le vamos a agregar dos botones (btMostrarHijo1, btMostrarHijo2) y un panel (panelContenedor), así:

así luce el form padre

Y en los Forms hijos agregamos etiquetas grandes y distintivas (o lo que quieras agregar), así:

Así lucen los forms hijos

Ahora, en el lado que nos gusta (el lado del código) veamos cómo implementar estos formularios en el panel, en el evento click del botón btMostrarHijo1 agregamos el siguiente código:

private void btMostrarHijo1_Click(object sender, EventArgs e)
{
            if (this.panelContenedor.Controls.Count > 0)
                this.panelContenedor.Controls.RemoveAt(0);
            Hijo1 form = Application.OpenForms.OfType<Hijo1>().FirstOrDefault();
            Hijo1 hijo1 = form ?? new Hijo1();
            hijo1.FormBorderStyle = FormBorderStyle.None;
            hijo1.Dock = DockStyle.Fill;
            this.panelContenedor.Controls.Add(hijo1);
            this.panelContenedor.Tag = hijo1;
            hijo1.Show();
}

La explicación de cómo funciona este código es muy simple, primero preguntamos si existe algún control en el interior del panel, de ser verdadero lo eliminamos. Luego creamos una nueva instancia del formulario a agregar Luego preguntamos si existe algún formulario del tipo Hijo1 que ya este abierto, si existe usamos esa misma instancia, de lo contrario creamos una nueva y sobre este objeto reescribimos algunas de sus propiedades, TopLevel establece si el formulario debe mostrarse como ventana nivel superior, FormBorderStyle define el estilo de los bordes de nuestro formulario (en nuestro caso no queremos mostrarlos), Dock establece como se acoplara el control a su contenedor principal (en nuestro caso queremos que rellene todo el panel), Por ultimo lo agregamos al panel, establecemos la instancia como contenedor de datos de nuestro panel y lo mostramos, el resultado se verá así:

Y si tengo 50 botones en mi formulario padre, ¿tengo que escribir todo este código 50 veces? La respuesta es NO, por fortuna para nosotros podemos escribir un método que nos ahorre a un más el trabajo, en nuestro caso crearemos un método void (sin retorno de datos) que recibirá como parámetro la instancia del  Formulario a mostrar, así:

private void AddFormInPanel(Form fh)
{
            if (this.panelContenedor.Controls.Count &amp;gt; 0)
                this.panelContenedor.Controls.RemoveAt(0);            
            fh.TopLevel = false;
            fh.FormBorderStyle = FormBorderStyle.None;
            fh.Dock = DockStyle.Fill;
            this.panelContenedor.Controls.Add(fh);
            this.panelContenedor.Tag = fh;
            fh.Show();
} 

Y para acudir a este, desde el evento click del botón lo hacemos así:

private void btMostrarHijo2_Click(object sender, EventArgs e)
{            
        var form = Application.OpenForms.OfType<Hijo2>().FirstOrDefault();
        Hijo2 hijo = form ?? new Hijo2();
        AddFormInPanel(hijo);
}

De esta forma es mucho más sencillo y agradable el trabajar con formularios contenidos dentro de otros.

Descarga el ejemplo

Bien espero les sea de utilidad en sus proyectos.

Hasta el próximo post.

92 comentarios sobre “Forms en paneles, adiós a los formularios MDI

  1. Buen post amigo Nicolas, ademas recodermos que ya webforms esta siendo reemplazado por un lenguaje basado en marcas como lo es WPF, el cuál es muy liviano, portente y permite una personalizaciín increible sin necesidad de estar matandonos la cabeza creando controles… y por cierto los formularios MDI no están soportados nativamente en WPF, en codeplex existe un proyecto con el cual los podemos implementar !

  2. Eh echo este ejemplo en mi sistema abro normal pero cuando quiero
    abrir el mismo formulario me sale este error:

    No se puede obtener acceso al objeto elimnado.
    Nombre de objeto :(en mi caso) ‘Frm_Obra’

    Cual podria ser la solucion. Gracias.

    1. Hola, lo que te entiendo es que En tu form padre cuando intentas abrir DOS veces el mismo form hijo, es decir que das dos veces click en el boton que abre a ese hijo, te salta esa excepcion?? caray pues he probado y no, hice la prueba así como te comento pero no salta la excepcion.
      Si no es este el problema, especificame un poco mas a detalle que haces para que salga y te ayudo.
      Saludos y gracias por el comentario.

      1. Ya lo reolvis eske de nu menu me llama a varios forms… mejor hice un formPadre MDI pero igual lo que publicaste ya chevere

        Gracias…

  3. Amigos d esta pagina tengo un problema en i proyecto csharp.net es el siguiente:
    En mi proyecto Presentacion donde van los formularios eh creado 2 carpetas con forms dentro, pero ahora lo quiero es crear otra carpeta e incluir un formulario hasta ahi vamos bien pero cuando voy a la clase Program.cs , la me dice de donde quiero arrancan, en esta parte del codigo:
    Application.Run(new ……()); en los puntos suspensivos quiero colocar mi carpera recien creada y el form que acabo de incluir pero no me sale en el cuadro intelgente
    Alguna ayuda ..

    Gracias.

    1. Hola, para esto que deseas hacer, solo necesitas agregar la referencia a la carpeta que esta dentro de la solucion, así:

      using PruyetcName.Carpeta;

      Y luego en el metodo Run de Application, lo haces normal:

      Application.Run(new NombreForm());

      Saludos

  4. buenas,
    tengo un problema cuando intento seleccionar el contenido de un textbox con el mouse o haciendo click-derecho dentro de uno, todo esto cuando tengo un formulario dentro del panel.
    ¿saben alguna solucion?

    gracias.

    1. Hola,

      mm… esta muy rara la situcion que comentas, pasa con todos los TextBox??… descargue el ejemplo que publique en el SkyDrive para probar si con este pasaba y no, osea SI pude seleccionar texto con el mouse, y acudir al menu contextual del mismo, pude copiar, pegar y demas. Si quieres podrias especificar mas detalles y miramos una solucion 🙂

      Saludos y gracias por la pregunta.

  5. muy buena explicación, estaba buscando justo este tipo de ejemplos y me vino muy bien para hacer una pantalla principal en la que no se llene de ventanas.

    Muchas gracias

  6. Hola, quisiera que me ayudaran en algo tengo el form_principal que tiene un boton q me lleva al form_hijo1….y en el form_hijo1 hay un boton que me lleva al form_hijo2…el problema esta en que cuando le doy click para abiri el form_hijo2, este no me aparece contenido en el panel del form_principal sino que aparece aparte…..sera que alguien me puede ayudar con esto…..Gracias

  7. ESTOY TRABAJANDO CON ALGO SIMILAR AL ULTIMO EJEMPLO (FORM HIJOS CONTENIDOS EN UN PANEL DEL FORM PADRE) MI DUDA ES: COMO SE LE HACE PARA GUARDAR INFORMACION DEL FORM HIJO EN EL PADRE SI AMBOS ESTAN ABIERTOS AL MISMO TIEMPO, O COMO LE ALMACENA INFORMACION CONTENIDA EN EL FORM HIJO EN EL PADRE POR MEDIO DE BOTON GUARDAR

    1. Hola.

      Antes de nada, perdón por tardar en mi respuesta 😦 espero ya lo tengas solucionado.

      Ahora bien, no entiendo bien a que te refieres con guardar información de un hijo a un padre :-S … pero si entiendo bien lo que planetas se puede solucionar con Eventos, es decir exponer un evento en el padre y que este se dispare cuando se haga alguna modificación en uno de los hijos… si necesitas más detalles porfa infórmame y te colaboro con un ejemplo 😀

      Saludos.

    1. Hola.

      umm, así a simple vista se me ocurre que puedes resolverlo con una colección de formularios, algo como un List donde al hacer clic con el botón de navegación hagas algo como: var form = Formularios[++_indexActual] y el resultado lo pases al AddFormInPanel(form)

      Saludos.

  8. exelente pero como hago para que se comuniquen el form1 con el padre, en si ya lo tengo eso pero cuando pongo this dentro del show me sale excepcion, me explico cuando pongo hijo1.show(this) me dice remove the form any parent form before calling show

    1. Discúlpame… pero no entiendo :-S o sea, ese problema se debería resolver con esta validación :
      if (panelContenedor.Controls.Count > 0)
      panelContenedor.Controls.RemoveAt(0);

      Pero no entiendo bien que es lo que haces cuando dices comunicar el Form1 con el padre… podrías agregar algo de tu código?

      Saludos.

  9. Hola, una duda, en una aplicacion que tengo he sustituido mis forms mdi por forms con panel, el problema que tengo es que en la ventana hijo no me aparecen los textos de mi tooltip, cuando uso los form mdi se muestran sin problema.

  10. Excelente info, lo que si estoy investigando y aun no pude encontrar es como se hace para hacer referencia a los controles que tengo en el formulario hijo desde el formulario padre una vez que ya esta cargado dentro del Panel, agradeceria tu ayuda, desde ya muchas gracias

  11. tengo un formulario padre el cual tiene un link para un hijo…queda bien dentro del panel hijo pero cuando pretendo que del form.hijo llame otro form2…el form2 nuevo no queda en el panel…en el form hijo le coloco un panel y el form2 aparece en el panel…pero cuando retorno con un close al formulario hijo el panel queda y el panel no desaparece en el fom hijo

  12. Excelente. Buen trabajo.
    Generalmente no comento estos post, pero el tuyo, lo merece con creces.
    Simple, fácil y rápido! 😉
    Saludos desde Colombia.

    Muchas gracias!

  13. hola tengo un proyecto en el cual tengo dos paneles en los cuales e cargado un formulario en cada uno y deseo llamar desde un formulario hijo llamar a otro en el otro panel

  14. hola, porfavor hechenme la mano para resolver mi problema ya que llevo unas dos semanas intentando resolverlo, antes que nada no soy experto en programacion pero estoy enrolado y aprendiendo mas sobre la marcha…estoy remplazando los MDI por paneles, tengo un Form principal (padre) con una interfaz de 3 paneles, simila a outlook, en el cual utilizo un TreeView para cambiar de ventanas en un panel (Forms hijos).
    En los form hijos estoy utilizando DataGridView para presentar mis datos, es asunto es que cuando ejecuto el programa y doy clic en un treeNode, se abre mi ventana, en este caso, el panel con el dataGridView correcto, vualvo a darle clic y se queda la misma ventana (panel), pero se agregan los mismos datagridview dos veces y asi sucesivamente se van incrementando…como le puedo hace para que no suceda esto??
    a continuacion coloco el codigo…de antemano gracias y espero aber sido claro en el planteamiento de mi problema.

    ==Este es el codigo de mi Form padre para remplazo de MDI por paneles:==

    private void pnl3_Paint(object formHijo)
    {
    if (this.pnl3.Controls.Count > 0)
    this.pnl3.Controls.RemoveAt(0);
    Form fh = formHijo as Form;
    fh.TopLevel = false;
    fh.FormBorderStyle = FormBorderStyle.None;
    fh.Dock = DockStyle.Fill;
    this.pnl3.Controls.Add(fh);
    this.pnl3.Tag = fh;
    fh.Show();

    }
    private void SelecForm(object sender, TreeNodeMouseClickEventArgs e)
    {
    ((TreeView)sender).SelectedNode = e.Node;

    if (e.Node.Name == «TreeGroups»)
    {
    pnl3_Paint(new GrupoForm());

    }
    if (e.Node.Name == «TreechildSala1»)
    {
    pnl3_Paint(new frmSala1());

    }

    }
    ===================================================================================================

    ==Este es el codigo de mi Form hijo==
    public partial class GrupoForm : Plantilla
    {
    public static DataGridView dgvPantalla = new DataGridView();
    public static TcpListener Servidor = new TcpListener(IPAddress.Any, 4000);
    public static List Clientes = new List();
    public static List IDClientes = new List();
    public static List PuertosOcupados = new List();

    public static int SFILA = 0;

    public GrupoForm()
    {
    InitializeComponent();
    dgvPantalla.Dock = DockStyle.Fill;
    dgvPantalla.Columns.Add(«Computadora», «Computadora»);
    dgvPantalla.Columns.Add(«Inicio», «Inicio»);
    dgvPantalla.Columns.Add(«Final», «Final»);
    dgvPantalla.Columns.Add(«Costo», «Costo»);
    dgvPantalla.Rows.Add(100);
    dgvPantalla.ReadOnly = true;
    gbD.Controls.Add(dgvPantalla);
    dgvPantalla.RowEnter += new DataGridViewCellEventHandler(dgvPantalla_RowEnter);

  15. Hola que tal!

    Tengo tiempo usando panel como si fueran MDI y me ha funcionado muy bien hasta ahora que se me presento un gran inconveniente, Quisiera ver si puedes ayudarme a decirme como puedo hacer para abrir un Form3 en el panel del Form1 mandándolo hablar en un boton del Form2 previamente cargado en el panel del Form1, espero me haya explicado.

    Saludos, excelente Blog =)

    1. Hola Hermilio, lamento la tardanza en responder (Y espero hayas logrado ya resolver tu inquietud), pero andaba algo ocupado :S.
      Podrías ser un poco más explicito? no entiendo bien la parte de: «del Form1 mandándolo hablar en un boton del Form2» si tienes algún fragmento de código para revisarlo…

      1. Que onda como estas?, Decidí resolver el problema que tenia de otra manera pero igual si me sirvió mucho el código que muestras aquí. Muchas gracias igual por la ayuda =)

        Saludos.

  16. Hola, no soy un experto en C# así que voy a hablar con bastante desconocimiento sobre el tema y puede que lo que comente tenga sentido o que no tenga sentido alguno.
    Yo he utilizado la solución que propones que también he visto en algún otro sitio pero… RemoveAt creo que solo elimina la referencia Control, en nuestro caso un Form, de la colección Controls pero no lo libera.
    Al hacer eso, ese Form deja de estar referenciado (tanto Hijo1 hijo1 = new Hijo1(); como Form fh = formHijo as Form; al abandonar el ámbito de su función pierden esa referencia y luego al hacer RemoveAt pierden la única referencia que tenían, esto hace que queden ocupando una zona de memoria, hasta que el colector de basura entre en acción, si entra.)
    Yo he probado lo siguiente:
    if (this.panelContenedor.Controls.Count > 0)
    ((Form)this.panelContenedor.Controls.Controls[0]).Close();
    Hice una pequeña comparativa de uso de la memoria (que tampoco se si fue fidedigna) y con RemoveAt se iba incrementando y con Close no.
    Observé un problema con la solución de Close: si se clickeaba muy rápido (muy muy rápido) el botón que lanza este método, cuando llega a la línea del .Show arroja un System.ObjectDisposedException. Esto lo solventé con una variable bool a modo de semáforo para no procesar un click hasta que no termine la función.
    Si alguien puede opinar algo sobre el tema estaría bien, saludos.

  17. PD. quería decir ((Form)this.panelContenedor.Controls[0]).Close(); en lugar de ((Form)this.panelContenedor.Controls.Controls[0]).Close();

  18. Hola.
    ¡Gracias por el comentario @Pepito! no me fijé en el momento de escribir el articulo que los Forms claramente están quedando abiertos (los años pasaron y no me di cuenta) y se abren nuevos (new Form()) cada vez que se hace click para cambiar de *hijo*… Tu solución está bien, aunque implica que se cierre, se haga dispose y se vuelva a crear el objeto con cada click.
    Otra opción puede ser reutilizar el objeto (el form instanciado) algo de la forma:

                Hijo1 form = Application.OpenForms.OfType<Hijo1>().FirstOrDefault();
                Hijo1 hijo1 = form ?? new Hijo1();
    

    Voy a hacer mediciones y a editar el articulo.

    Nuevamente muchas gracias!

    Saludos.

  19. Tengo el siguiente inconveniente, si cambiamos esta línea:
    hijo1.FormBorderStyle = FormBorderStyle.None;

    por

    hijo1.FormBorderStyle = FormBorderStyle.Sizable;
    //O cualquier otro valor: FixedSingle, Fixed3D, FixedDialog, etc.

    Ya no se pude seleccionar el contenido de los TextBox con el mouse dentro del formulario HIJO, lo que resulta realmente incómodo. ¿Alguna sugerencia?

  20. Hola buen día, quisiera que me ayudaran con este problema, tengo un form1(padre) el cual contiene un panelPrincipal en el cual se carga otro form2(hijo) que a su vez contiene otro panelSecundario que contiene un form3(hijo de hijo), como hago, para mediante código en este ultimo form3, volver al principio osea antes de que estuvieran cargados el form3 y form2, osea que solo este el form1(padre) y el panelPrincipal sin nada contendido.

  21. Gracias por éste artículo primeramente. Mi duda es cómo manejar los eventos de éste formulario hijo. Por ejemplo: Estoy validando unos textbox en el formulario hijo y al final verifico si están if (this.ValidateChildren) pero cómo éste formulario hijo está dentro del panel. Me lo tomá como si el (this) fuera el formulario padre y no el hijo.
    Espero tu ayuda, gracias de antemano.

  22. Buenas amigos, tngo el siguiente problema cuando cargo 2 formularios diferente en un panel.
    la navegacion es esta bien pero cuando hago alun cambio, los controles no se actualizan.

  23. Exelente Bro. Solo he tenido que cambiar
    if (this.panelContenedor.Controls.Count &gt; 0) por if (this.panelContenedor.Controls.Count > 0) y listo…..gracias

  24. Hola, buen blog pero tengo una consulta, uno usa un mdi container pq quiere trabajar varios forms, pasar del form 1 al form2 cuando se quiera sin perder la info, igual pasa con los tabs, en tu caso como se haria? si paso al siguiente form se pierde lo que tenia en el anterior.

  25. Hola nicolo !!! gracias por la solucion. Tengo una consulta para hacerte, si por ejemplo en el form padre tengo un boton que se llama alta de socio en el cual abre en el panelContenedor un form, que cree aparte que es para llenar un formulario, y en este nuevo form tengo un boton cancelar y quiero que cierre el form desde el form padre en el panelContenedor ¿Como hago eso?

  26. Hola me gusto mucho gracias aunque con algunas carencias es mas facil, pero quisiera sabes si se puede remodificar el panelcontenedor desde el formulario q cargaste en el panelcontenedor? me he quebrado la cabeza no ayo como xD gracias de nuevo

  27. Hola, gracias por el aporte estoy queriendo implementar esta solución con C# en VS2013 pero al querer abrir el formulario me da un error que dice «No se puede agregar un control de nivel superior a un control.» en esta linea de código this.panelContenedor.Controls.Add(hijo1);
    me puedes ayudar gracias

    1. Aqui te va el codigo en VB

      Private Sub ToolStripButton1_Click(sender As Object, e As EventArgs) Handles ToolStripButton1.Click
      Dim formaAbierta As FrmPVMemorandum = Application.OpenForms.OfType(Of FrmPVMemorandum)().FirstOrDefault()
      Dim forma As FrmPVMemorandum

      If formaAbierta Is Nothing Then
      forma = New FrmPVMemorandum
      Else
      forma = formaAbierta
      End If

      AgregaPanel(forma)
      End Sub

      Private Sub ToolStripButton2_Click(sender As Object, e As EventArgs) Handles ToolStripButton2.Click
      Dim formaAbierta As FrmPVConsultaViajes = Application.OpenForms.OfType(Of FrmPVConsultaViajes)().FirstOrDefault()
      Dim forma As FrmPVConsultaViajes

      If formaAbierta Is Nothing Then
      forma = New FrmPVConsultaViajes
      Else
      forma = formaAbierta
      End If

      AgregaPanel(forma)
      End Sub

  28. Private Sub ToolStripButton1_Click(sender As Object, e As EventArgs) Handles ToolStripButton1.Click
    Dim formaAbierta As FrmPVMemorandum = Application.OpenForms.OfType(Of FrmPVMemorandum)().FirstOrDefault()
    Dim forma As FrmPVMemorandum

    If formaAbierta Is Nothing Then
    forma = New FrmPVMemorandum
    Else
    forma = formaAbierta
    End If

    AgregaPanel(forma)
    End Sub

    Public Sub AgregaPanel(ByVal forma As Form)
    If (Me.Panel1.Controls.Count > 0) Then
    Me.Panel1.Controls.RemoveAt(0)
    End If

    forma.TopLevel = False
    forma.FormBorderStyle = Windows.Forms.FormBorderStyle.None
    forma.Dock = DockStyle.Fill
    Me.Panel1.Controls.Add(forma)
    Me.Panel1.Tag = forma
    forma.Show()
    End Sub

  29. Una duda.. tal vez soy el único al que le pasa.. al correr el programa con el depurador y cerrar todas las ventanas… el depurador no se detiene. Yo creo que es por que no se han cerrados los formularios que fueron creados e insertados en el formulario padre.

    A alguien más le ha pasado ??

  30. Disculpen, he intentado hacer que el formulario tenga un efecto de transparencia con el opacity, sin embargo cada vez que lo hago no me lo respeta ya que que este se encuentra en el panel, alguien puede ayudarme con esto?

  31. Yo lo quiero hacer de la misma forma pero, sólo con un boton y un combobox para seleccionar el form que quiero abrir, me podría ayudar con el codigo porfavor gracias

  32. amigo muy buena la idea de los paneles, una pregunta si yo quiero enviar un valor desde el boton a un label dentro del formulario que estoy llamando en el panel como lo haria estoy intentasndo pero no lo consigo

    1. Para la comunicación entre padre e hijo, he usado delegados.

      frmHijo hijo = new frmHijo();

      EjecutarMetodoHijo = new MetodoDelegate(frmHijo.MetodoHijo)
      ..

      // en frmHijo

      public string MetodoHijo()
      {
      return «Hola»;
      }

      // en frmPadre

      label.Text = EjecutarMetodoHijo();
      ..

  33. que buen material espero siga subiendo este tipo de aplicables

    tengo un problema y espero me ayude…….. tengo un WPF y en este tengo agregado un windows from en el cual le puse un picturebox el problema es que no puedo acseder al picturebox desde mi wpf espero me ayude no puedo aser que mi picturebox se empiece a declarar en mi wpf espero me ayude

  34. Que tal el siguiente error..
    Exception thrown: ‘System.ArgumentException’ in System.Windows.Forms.dll

    Additional information: No se puede agregar un control de nivel superior a un control.

    utilizo visual estudio.. alguna idea? el código es el mismo que publicaron en el post. algún tiempo funciono bien, sin embargo tengo este error en la siguiente línea:

    this.PanelContenedor.Controls.Add(radioportatil);

    Muchas gracias por su ayuda!!

  35. Saludos para usted Maestro…
    Nuestra pregunta es la siguiente: al implementar su ejemplo el cual copiamos de forma íntegra, y luego al modificar el formulario que llamamos (hijo1), donde hemos colocado un dataGridView1 queremos que sucedan dos cosas:
    que al dar doble click en el datagridView1, que solo tiene dos datos: codigocliente y nombrecliente

    1.- capturar los registros seleccionado en el dataGridView1 y llevarlo al formulario padre a un textbox_codigocliente y textbox_ nombrecliente
    2.- cerrar el formulario (hijo1)
    Pero hasta el momento no hemos podido hacer esto. Cuando modificamos la opción\
    hijo1.ShowDialog ();
    Gracias por la Transferencia del conocimiento…

  36. No se si solo me este pasando a mi, pero se me abre otra ventana negra de los formularios hijos cuando los mando llamar desde el formulario padre, es decir si se muestran los formularios hijos en el panel2 del splitContainer pero ademas se abre otra vez el mismo formulario hijo por fuera y con todo su contenido en negro. Como puedo omitir que se abra por fuera?

    1. Ya vi cual es mi problema, pasa que adicional a lo que dicta este manual tambien agregue una librería de MetroFramework y eso es lo que hace que se abra la otra ventana negra, pero sigo sin saber como hacer para resolver eso.

  37. Hola, tengo mi form contenedor y ese tiene el panel donde se abren los form hijos, mi form contenedor tiene los botones para mostrar los hijo y hasta hay todo bien, ahora la cuestión es que si ya abrí un form hijo y ese form hijo también tiene botones y al presionar un botón del form hijo quiero que se muestro el form hijo del hijo en el panel del form contenedor como puedo hacer eso? saludos y gracias de antemano por su ayuda

  38. Soy el unico que al usar esto
    if (this.bunifuCards1.Controls.Count > 0)
    {
    this.panelContenedor.Controls.RemoveAt(0);
    }
    El formulario nuevo se sobrepone sobre el anterior?? Me toca cliclear varias veces hasta que salga el que quiero…
    Pero si uso
    this.panelContenedor.Controls.Clear();
    No tengo problema alguno.
    Estoy bien? o que me aconsejan?

  39. Hola es una muy buena idea el implementar esta solución, a mi me da solo un pequeño error cuando carga el form hijo muestra como carga cada elemento del form parpadeando hasta adaptarse al panel. si alguien tiene alguna idea de que puede causar esto se lo agradecería

  40. Cargo los Forms hijos comentando las líneas
    //hijo1.FormBorderStyle = FormBorderStyle.None;
    //hijo1.Dock = DockStyle.Fill;
    Para poder trabajar con 2 forms hijos abiertos, el caso es que para alternar entre uno y otro , tengo que pulsar sobre el titulo de cada ventana , sino no se superpone a la otra, poniendo el foco en el hijo de atrás no me lleva al front ese form, si alguien me puede ayudar…
    Aquí queda mas claro lo que estoy haciendo:
    https://stackoverflow.com/questions/56967012/how-to-bring-to-the-front-form-with-focus-in-textbox-or-any-other-control-in-tha?noredirect=1#comment100526022_56967012
    Gracias.

Replica a aby Cancelar la respuesta