MDI es el acrónimo de Multiple Document Interface, las Interfaces de Documento Múltiple hace referencia a una estructura de formularios en donde existe un “padre” o formulario contenedor y los demás son formularios “hijos” que se mantienen dentro del contenedor.
Es la estructura que mantiene Access, como se ve en la imagen arriba y hasta no hace mucho tiempo también en Excel, y continúa siendo práctico de usar en software de gestión y acceso a recursos varios.
Interfaz de Documento Múltiple en Visual Studio
En la edición Community 2022, versión 17.7.4 ya tenemos disponible una clase para agregar una interfaz de este tipo:
Este ya incluye varios elementos básicos como una barra de menú con las opciones clásicas de Archivo, Editar, Ver… y lo mismo en su barra de botones (herramientas):
Pero esta vez se trata de familiarizarnos con propiedades y métodos que nos permitan entender el funcionamiento y dar soluciones en este tipo de estructura.
Nuevo Proyecto: FormulariosMdi
Inicio un nuevo proyecto en C# del tipo Aplicación de Windows Forms (.NET Framework) al que nombré como FormulariosMdi.
Una vez tengamos el formulario inicial cambiemos el valor de su propiedades:
Aparte del cambio en el color de fondo no se notará otra diferencia, le agregamos un control MenúStrip con las opciones siguientes:
Dejamos un momento nuestro formulario “padre” y pasemos al diseño de los formularios “hijos”.
Los Formularios “hijos”
Agregamos un formulario al proyecto, seleccione su proyecto (no la solución) en el Explorador de soluciones, menú Proyecto, clic en Agregar formulario (Windows Form)…, lo nombramos frmPrimero y agregamos:
Repetimos la operación para agregar el formulario frmSegundo.
Para identificar correctamente cada formulario asignaremos a su barra de título el texto “Formulario Primero” y “Formulario segundo” respectivamente, sin las comillas.
Terminando el Menú Principal
Desde la opción Ventana1 y Ventana2 debemos abrir una instancia de los formularios primero y segundo respectivamente, vamos con la implementación de cada ítem de menú, doble clic y le damos las instrucciones:
La primera línea crea una instancia de la clase frmPrimero y frmSegundo, la segunda línea hace visible nuestro objeto, ejecutemos para probar:
Los formularios se muestran, pero no como hijos ya que es posible sacarlos del contenedor, son ventanas independientes cada una de las otras, debemos agregar una instrucción para indicarles a las ventanas hijos quien va a actuar como contenedor,
La propiedad MdiParent nos permitirá indicarle quien es el formulario principal en esta estructura de documentos múltiples, para señalar al formulario actual usaremos la palabra reservada this, nuestro código queda así:
Y ejecutamos.
Ahora estarán actuando correctamente como objetos contenedores y contenidos respectivamente.
La implementación nos permite tener varias instancias de cada ventana hija, en algunos entornos de producción eso está bien, sin embargo, en otras circunstancias quizá solo necesitemos permitir una sola instancia ¿Cómo controlamos ese número?
Formulario Único
Modificaremos la forma de instanciar el segundo formulario para permitir solo una instancia del mismo, para ello debemos modificar la definición de la clase de frmSegundo, clic derecho en el mismo Ver código o la tecla de función F7:
Implementaremos una variable para conocer si existe una instancia del formulario omitiendo el constructor que estamos usando, si no existe una instancia (null) la creamos, caso contrario solo mostramos la instancia que ya existe, la variable debe ser de tipo frmSegundo y la nombraremos frm:
private static frmSegundo frm = null;
La variable frm la iniciamos como null, ahora debemos agregar la función que valide el valor de frm:
//La función es abrirVentanaUnica() del tipo frmSegundo
public static frmSegundo abrirVentanaUnica()
{//Si es null instanciamos
if (frm == null)
{
frm = new frmSegundo();
return frm;
}//Si existe una instancia la retornamos
return frm;
}
Modifiquemos el código en el formulario contenedor, usaremos la función abrirVentanaUnica() omitiendo el constructor actual:
Si ejecutamos en este momento se genera un error al cerra la ventana única y tratar de abrir una nueva instancia, esto se debe a que la variable frm no está en null, así que trata de mostrar esa instancia, pero no es posible hacerlo debido a que ya la cerramos, así que al cerra la ventana única debemos pasar la variable frm a null, en el evento Closed de frmSegundo (cuando se cerró el formulario) agregamos:
frm = null;
Con eso se soluciona la excepción anterior, pero si la instancia única está oculta detrás de otra ventana hermana se mantendrá así oculta, para traerla al frente agregamos una línea para el método BringToFront(), finalmente quedaría así:
private void mnuVentana2_Click(object sender, EventArgs e)
{
frmSegundo segundo = frmSegundo.abrirVentanaUnica();
segundo.MdiParent = this;
segundo.Show();
segundo.Text = "Ventana única";
segundo.BringToFront();
}
Volvamos a ejecutar y tenemos solucionado el ejercicio.
Plus: Numerando las Instancias
Para el caso de frmPrimero que permitirá varias ventanas, vamos a numerarlas como sucede en Excel, Word y otros: Libro 1, Libro 2, Libro 3,…
Necesitamos de una variable que actúe como contador, lo asignamos al título de cada instancia y lo incrementamos, el contador solo se restablece cuando se reinicia toda la aplicación.
En nuestro formulario contenedor, a continuación de la clase agregamos la variable estática de tipo entero:
static int x = 0;
Y en en el código para instanciar frmPrimero:
Al ejecutar:
¿Organizar las ventanas? Eso lo dejamos para un ejercicio siguiente.
Podría interesarte ver otros posts sobre C#. Y los esperamos también en Facebook, Blogger, WordPress , Canal de Telegram y en WhatsApp ¡Éxitos! ☻
No hay comentarios.:
Publicar un comentario
Tu comentario