sábado, 28 de marzo de 2015

Windows Forms. MDI Child sin ControlBox

En muchas ocasiones, al desarrollar nuestras aplicaciones de escritorio, deseamos hacer navegar al usuario entre diferentes pantallas sin necesidad de ir abriendo diferentes ventanas.

Para lograrlo podemos implementar diferentes soluciones, por ejemplo tener diferentes paneles o controles de usuario ocultos en un formulario que se van mostrando según va navegando el usuario de una pantalla a otra.

Otra posible solución es la de usar un formulario MDI e ir mostrando en su interior los diferentes formularios hijos maximizados, pero ¿cómo evitamos que el usuario pueda redimensionar o minimizar el formulario hijo? ¿Cómo podemos conseguir que nuestro formulario hijo ocupe todo el espacio del formulario contenedor y que no nos muestre los botones de minimizar, restaurar y maximizar?



Pues la solución es más simple de lo que podríamos pensar. Basta con establecer la propiedad Dock del formulario hijo a DockStyle.Fill y la propiedad FormBorderStyle a FormBorderStyle.None.

Para mostrar el funcionamiento basta con crear un nuevo proyecto de Aplicación de Windows Forms. En el formulario Form1 insertamos el siguiente código:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MDIChildsSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.IsMdiContainer = true;
            this.Load+= Form1_Load;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Form childForm = new Form() { 
                MdiParent = this, 
                Dock = DockStyle.Fill, 
                FormBorderStyle = FormBorderStyle.None 
            };
            Label label = new Label() { 
                Text = "Pantalla 1", 
                Font = new Font(this.Font.FontFamily, 32, FontStyle.Bold), 
                AutoSize = true 
            };
            childForm.Controls.Add(label);
            Button button = new Button() { 
                Text = "Ir a Pantalla 2", 
                Top = 80, 
                AutoSize = true 
            };
            button.Click += button_Click;
            childForm.Controls.Add(button);
            childForm.Show();
        }

        private void button_Click(object sender, EventArgs e)
        {
            Form childForm = new Form() { 
                MdiParent = this, 
                Dock = DockStyle.Fill, 
                FormBorderStyle = FormBorderStyle.None 
            };
            Label label = new Label() { 
                Text = "Pantalla 2", 
                Font = new Font(this.Font.FontFamily, 32, FontStyle.Bold), 
                AutoSize = true 
            };
            childForm.Controls.Add(label);
            this.ActiveMdiChild.Hide();
            childForm.Show();
        }

    }
}
Public Class Form1

    Public Sub New()
        ' Llamada necesaria para el diseñador.
        InitializeComponent()

        Me.IsMdiContainer = True
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim childForm As Form = New Form() With {.MdiParent = Me, .Dock = DockStyle.Fill, _
                                                 .FormBorderStyle = FormBorderStyle.None}
        Dim label As Label = New Label() With {.Text = "Pantalla 1", _
                                               .Font = New Font(Me.Font.FontFamily, 32, FontStyle.Bold), _
                                               .AutoSize = True}
        childForm.Controls.Add(label)
        Dim button As Button = New Button() With {.Text = "Ir a Pantalla 2", .Top = 80, .AutoSize = True}
        AddHandler button.Click, AddressOf Button_Click
        childForm.Controls.Add(button)
        childForm.Show()
    End Sub

    Private Sub Button_Click(sender As Object, e As EventArgs)
        Dim childForm As Form = New Form() With {.MdiParent = Me, .Dock = DockStyle.Fill, _
                                                 .FormBorderStyle = FormBorderStyle.None}
        Dim label As Label = New Label() With {.Text = "Pantalla 2", _
                                               .Font = New Font(Me.Font.FontFamily, 32, FontStyle.Bold), _
                                               .AutoSize = True}
        childForm.Controls.Add(label)
        Me.ActiveMdiChild.Hide()
        childForm.Show()
    End Sub

End Class



El código es sencillo.
El formulario se establece como contenedor MDI.
En la carga del formulario se crea y muestra un nuevo formulario hijo con una etiqueta con el texto Pantalla 1 y un botón que nos permitirá pasar a la segunda pantalla. Las propiedades Dock y FormBorderStyle del formulario hijo se establecen a DockStyle.Fill y FormBorderStyle.None respectivamente.
En el evento Click del botón se crea (y se muestra) un segundo formulario hijo con una etiqueta con el texto Pantalla 2. Las propiedades Dock y FormBorderStyle de este segundo formulario se establecen también a DockStyle.Fill y FormBorderStyle.None.

Si ejecutamos la aplicación y pulsamos en el botón Ir a Pantalla 2 podremos ver que conseguimos el efecto deseado.

Resultado del ejemplo

3 comentarios:

  1. Excelente ejemplo Sr.Asier, pero me queda la duda del uso de los paneles. ¿ También se utilizan para lograr este efecto? y si es así ¿ Es más complicado?.
    Saludos

    ResponderEliminar
    Respuestas
    1. Efectivamente. También puedes mostrar un formulario dentro de un panel y lograr este mismo efecto.
      La verdad es que este ejemplo en concreto lo creé de esta forma porque fue a partir de una consulta de un usuario, pero podría hacerse perfectamente incluyendo los formularios en un panel.

      Por complejidad, la misma, es prácticamente el mismo código.

      La ventaja de utilizar un formulario MDI es que tienes el resto de funcionalidades que este te aporta: poder mostrar diferentes formularios y manejar la visualización de cada uno, navegar entre ventanas, integrar los menús de los formularios hijos con los de la ventana principal, etc. Si no vas a utilizar estas funcionalidades adicionales del MDI se puede utilizar indistintamente cualquiera de los dos métodos.

      Eliminar
  2. Muchas gracias, me sirvió bastante este ejemplo

    ResponderEliminar