Guía No. 7 Programación I
Guía No. 7 Programación I
Guía No. 7 Programación I
7 1
Implementar herencia de formularios con los controles definidos en el IDE de Microsoft Visual C#.
Crear aplicaciones Windows Forms utilizando formularios MDI.
Introducción
Recordemos cuando estamos utilizando un procesador de texto en el que estamos escribiendo una tarea, y antes
de terminar de escribir esa tarea, comienza a escribir otro documento, y posiblemente otro, y tenga los tres
documentos en la pantalla al mismo tiempo, en ventanas escalonadas (cascada), o en ventanas en forma de
mosaico, o simplemente tapando unas a otras completamente. Los tres documentos están en su procesador de
textos, y puede actuar sobre uno u otro simplemente eligiendo el deseado mediante el mecanismo que le
proporciona su procesador de textos. Este sistema no es ni más ni menos que una Interfaz de Documentos
Múltiples. En programación, a este tipo de aplicaciones las denominamos MDI (Multiple Document
Interface).
MDI = Multiple Document Interface ó Interfaz de Múltiples Documentos, es básicamente, un contenedor, que
te permite abrir dentro de él, múltiples ventanas; muy útil para las aplicaciones que requieren utilizar muchos
formularios y que no se pierda el control de estos.
Cuando necesitamos trabajar múltiples “vistas” dentro de nuestros formularios por lo general recurrimos al
control TabControl, pero cuando necesitamos implementar una funcionalidad 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).
Formulario MDI.
Las aplicaciones MDI permiten mostrar varios documentos al mismo tiempo, cada uno de ellos en su propia
ventana. Las aplicaciones MDI suelen tener un elemento de menú Ventana con submenús que permiten cambiar
entre ventanas o documentos.
Un formulario MDI es un formulario (llamado “Padre” o “Parent”) que puede contener otros formularios
(llamados “Hijos” o “Child”).
2 Programación I. Guía No. 7
Procedimiento
Crear una carpeta con el nombre Práctica 7 para guardar los ejemplos y ejercicios, en el escritorio de su
computadora.
Guía 7 Ejemplo 1. Cómo crear una aplicación con formulario MDI, para definir formulario padre y
formulario hijo.
Creamos un nuevo proyecto “Windows Forms” y le colocamos como nombre “Guia 7”.
Lo primero que hacemos es cambiar el título del formulario y también el nombre por “FrmMDI”.
Luego agregamos un control MenuStrip, que utilizaremos para definir opciones de menú, entre las cuales
tendremos las opciones para llamar a los formularios hijos.
El formulario debe lucir parecido a la siguiente figura:
Figura 1.
Agregamos los nombres de las opciones del control MenuStrip de acuerdo con la figura 1.
Observemos que los nombres de las funciones tienen una letra subrayada. Para lograr esto, en la propiedad
“Text” de cada opción del menú, debemos colocar antes de la letra que queremos utilizar como ShortcutKey
(atajo), el símbolo “&”, como se observa en la siguiente figura:
Esto se hace, para que se pueda tener acceso a las opciones de menú con la combinación de teclas “Alt + Letra
subrayada”, durante el tiempo de ejecución.
Programación I. Guía No. 7 3
El siguiente paso es cambiar la propiedad “IsMdiContainer” al valor “True”. Esta propiedad indica si el
formulario será un contenedor MDI.
Al cambiar el valor de esta propiedad a “True”, el formulario cambia su interfaz, mostrando un recuadro de
color gris oscuro, indicando con ello que será el área donde se mostrarán los formularios “hijos”, tal como se
observa en la siguiente figura:
Damos doble clic en la opción “Salir” y en el evento “Click” de esta opción colocamos el siguiente código:
private void salirToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit(); // Otra forma de salir de una aplicación
}
De igual manera, le agregamos algunos controles, de tal manera que podamos diferenciarlo de los otros dos
formularios existentes en el proyecto, podría tener el siguiente aspecto:
Ahora procedemos a codificar las opciones de menú que llamarán a los dos formularios “hijo” que hemos
creado.
Damos doble clic en la opción de menú “Ejemplo 1” y en el evento “Click” de esta opción colocamos el
siguiente código:
private void ejemplo1ToolStripMenuItem_Click(object sender, EventArgs e)
{
// Definimos un objeto del tipo de formulario que queremos mostrar
FrmEjemplo1 ejemplo1 = new FrmEjemplo1();
Damos doble clic en la opción de menú “Ejemplo 2” y en el evento “Click” de esta opción colocamos el
siguiente código:
private void ejemplo2ToolStripMenuItem_Click(object sender, EventArgs e)
{
// Definimos un objeto del tipo de formulario que queremos mostrar
FrmEjemplo2 ejemplo2 = new FrmEjemplo2();
Damos clic en la opción de menú “Ejemplo 1” y el formulario cargará dentro del formulario principal
(formulario MDI) como observamos en figura 2.
Damos clic en la opción de menú “Ejemplo 2” y el formulario cargará dentro del formulario principal
(formulario MDI), compartiendo espacio con el formulario hijo previamente cargado, como observamos en la
figura 3.
Programación I. Guía No. 7 5
Figura 2.
Figura 3.
Podríamos dar clic en las opciones de menú “Ejemplo 1” y “Ejemplo 2” las veces que quisiéramos, y se
crearán tantos formularios hijos, como clic demos en dichas opciones, como podemos ver en la figura siguiente:
6 Programación I. Guía No. 7
Podemos agregar otras opciones al control MenuStrip para controlar que ventanas están abiertas, cual es la
ventana activa, y para ordenar la disposición de las ventanas hijas abiertas.
Para ello agregamos la opción “Ventanas” al control MenuStrip. También le agregamos como sub-opciones
las siguientes: Cascada, Mosaico Horizontal, Mosaico Vertical, Minimizar todo, Cerrar Todo. Recordar que la
letra subrayada, indica la letra para el atajo que combinaremos con la tecla “Alt”.
Al final nuestro formulario debe lucir como observamos en la siguiente figura:
Para indicar que en la opción de menú “Ventanas” queremos que se muestre un listado de todas las ventanas
que están abiertas, tenemos que modificar en el control MenuStrip la propiedad “MdiWindowListItem”,
indicando el elemento de menú “Ventanas”, así:
Ahora podemos probar nuestra aplicación, presionando la tecla “F5”. Procedemos a abrir varias ventanas hijas,
y luego damos clic en la opción “Ventanas” y observaremos todas las ventanas hijas que están abiertas y
también la ventana que se encuentra activa (que tiene el enfoque):
Programación I. Guía No. 7 7
Ahora procederemos a codificar las sub-opciones de la opción de menú “Ventanas”, las cuales utilizaremos
para ordenar los formularios hijos que estén abiertos en cualquier momento.
Damos doble clic en la opción “Cascada” y en el evento “Click” digitamos el siguiente código:
private void cascadaToolStripMenuItem_Click(object sender, EventArgs e)
{
/* Invocamos al método "LayoutMdi" y le indicamos que queremos organizar los formularios en
forma "Cascade" */
LayoutMdi(MdiLayout.Cascade);
}
Podemos probar nuestra aplicación y agregamos varios formularios y los desordenamos de tal manera que
luzcan parecido a la siguiente imagen:
Luego damos clic a la opción “Ventanas”, sub-opción “Cascada” y observaremos como los formularios hijos
se ordenan en forma de cascada, así:
Damos doble clic en la opción “Mosaico Vertical” y en el evento “Click” digitamos el siguiente código:
private void mosaicoVerticalToolStripMenuItem_Click(object sender, EventArgs e)
{
/* Invocamos al método "LayoutMdi" y le indicamos que queremos organizar los formularios en
forma "TileVertical" */
LayoutMdi(MdiLayout.TileVertical);
}
Damos doble clic en la opción “Minimizar todo” y en el evento “Click” digitamos el siguiente código:
private void minimizarTodoToolStripMenuItem_Click(object sender, EventArgs e)
{
/* Utilizamos un "for" para que recorra todos los formularios hijos en el espacio definido
para ello en el formulario MDI (formulario padre), obteniendo la cantidad de formularios
hijos */
for (int i = 0; i < this.MdiChildren.Length; i++)
{
// Le indicamos que minimice cada uno de los formularios hijos activos
this.MdiChildren[i].WindowState = FormWindowState.Minimized;
}
}
Damos doble clic en la opción “Cerrar Todo” y en el evento “Click” digitamos el siguiente código:
private void cerrarTodoToolStripMenuItem_Click(object sender, EventArgs e)
{
/* Utilizamos la estructura de repetición "foreach" para indicar que recorra todos los
formularios hijos en el espacio definido para ello en el formulario MDI (formulario padre) */
foreach (Form childForm in MdiChildren)
{
childForm.Close(); // Para cada formulario hijo, le indicamos que lo cierre
}
}
Por lo general, en aplicaciones MDI, es necesario que el formulario principal (padre) ocupe la totalidad de la
pantalla del equipo donde se ejecute. Para esto debemos modificar la propiedad “WindowState” y le colocamos
como valor “Maximized”:
Programación I. Guía No. 7 9
Podemos también cambiar el fondo de nuestro formulario principal. Para ello modificamos la propiedad
“BackgroundImage”, damos clic en el botón de tres puntos. En la ventana que aparece, seleccionamos la
opción “Archivo de recurso del proyecto” y damos clic al botón “Importar”.
En la ventana que aparece, buscamos la imagen que deseamos, la seleccionamos y damos clic en el botón
“Aceptar”.
Presionamos “F5” para ver como luce nuestro formulario MDI (ver figura 4).
Observemos que ahora el formulario ocupa toda la pantalla, y que el fondo se visualiza completamente.
Figura 4.
En las opciones de menú también puedo asignar combinaciones de teclas a las opciones que desee.
Por estándares de programación, es recomendable definir las opciones con “atajos” como los que hemos
definido anteriormente y asociar a las sub-opciones, combinaciones de teclas.
Para realizar esto debo modificar la propiedad “ShortcutKeys” de la opción a la que deseo asignarle esta
característica.
Modificaremos la sub-opción “Ejemplo 1”. Le asociaremos una combinación de teclas para poder acceder a
ella sin utilizar el mouse. Seleccionamos la opción en el control MenuStrip y en la ventana “Propiedades”
ubicamos la propiedad “ShortcutKeys”, como observamos en la figura siguiente:
Luego damos clic en el CheckBox “Ctrl” y luego clic en el ComboBox “Clave” para seleccionar la letra que
queremos asociar (ver figura 5).
Programación I. Guía No. 7 11
Figura 5.
Podemos probar nuestra aplicación, y no usar el mouse, sino que presionar en el teclado las teclas “Ctrl”+
tecla “1” y observaremos como se abre el formulario 1. Hacer lo mismo para cargar el formulario 2, es decir
presionar las teclas “Ctrl” y “2”.
También podemos agregar iconos a cada una de las opciones de nuestro menú. Para ello tenemos que modificar
la propiedad “Image”.
Agregaremos una imagen a la opción de menú “Ejemplo 1”. Seleccionamos la opción en el control MenuStrip
y en la ventana “Propiedades” ubicamos la propiedad “Image”, damos clic en el botón de tres puntos. En la
ventana que aparece, seleccionamos la opción “Archivo de recurso del proyecto” y damos clic al botón
“Importar”.
12 Programación I. Guía No. 7
Nos cargará una ventana que utilizaremos para buscar la imagen que deseamos, una vez lo ubicamos, lo
seleccionamos y damos clic al botón “Aceptar”:
Con esto nos aparecerá la imagen seleccionada como un icono a la par de la opción de menú:
Algo importante es que cuando agregamos imágenes con este método, todo se almacena en la carpeta
“Resources”.
Figura 6.
Les cambiamos a todos los objetos la propiedad “Text”, de acuerdo con la figura 6.
Le cambiamos la propiedad “Name” a los objetos de esta manera:
Control Valor
TextBox1 txtAlumno
Button1 btnBuscar
Modificaremos también el formulario “FrmEjemplo2”. Debe tener los siguientes controles: 2 Label y 1
ComboBox.
El formulario debe lucir parecido al que se muestra en la siguiente figura:
Figura 7.
Les cambiamos a todos los objetos la propiedad “Text”, de acuerdo con la figura 7.
Le cambiamos la propiedad “Name” a los objetos de esta manera:
Control Valor
ComboBox1 cmbAlumnos
Vamos a modificar la propiedad “Items” del ComboBox “cmbAlumnos”. Damos clic en los tres puntos que
aparecen en esta propiedad en la ventana “Propiedades”. Aquí escribiremos los nombres de los distintos
alumnos. En la propiedad “Text” colocaremos “Seleccione…”
Luego, damos doble clic en el cuerpo del formulario “FrmEjemplo1” para empezar a codificar.
14 Programación I. Guía No. 7
Definimos una variable de tipo instancia que nos ayudará a controlar cuando se instancia un formulario, así:
// Para controlar cuando se instancie este formulario
private static FrmEjemplo1 instancia;
Luego, definimos un método para manejar las instancias que se hagan de formulario “FrmEjemplo1”:
// Método para manejar si se ha cargado este formulario
public static FrmEjemplo1 GetInstancia()
{
if (instancia == null) // Si no hay un formulario abierto
{
instancia = new FrmEjemplo1(); // cargamos un formulario
}
return instancia; // retornamos la variable
}
Ahora damos doble clic en el botón “Buscar” y en el evento “Click” digitamos el siguiente código:
private void btnBuscar_Click(object sender, EventArgs e)
{
// Definimos un objeto del tipo de formulario que queremos mostrar
FrmEjemplo2 ejemplo2_vista = new FrmEjemplo2();
Ahora cambiaremos la forma en que abrimos el formulario “FrmEjemplo1”. Nos vamos al formulario
“FrmMDI”, y damos doble clic en la opción “FrmEjemplo1”, comentamos el código que ya teníamos y
digitamos este nuevo código:
private void ejemplo1ToolStripMenuItem_Click(object sender, EventArgs e)
{
/* Definimos un objeto del tipo de formulario que queremos mostrar, pero ahora lo haremos
usando el método "GetInstancia" definido en el formulario "FrmEjemplo1" */
FrmEjemplo1 ejemplo1 = FrmEjemplo1.GetInstancia();
Este error ocurre, pues recordemos que hemos definido una variable “instancia” que controla cuando un
formulario “FrmEjemplo1” ha sido cargado en el formulario “padre”, y cuando lo cerramos, no actualizamos
el valor de esa variable. Para corregirlo, tenemos que codificar el evento “FormClosing” del formulario
“FrmEjemplo1”, y agregamos el siguiente código:
private void FrmEjemplo1_FormClosing(object sender, FormClosingEventArgs e)
{
/* Esto hará que cuando el formulario se cierre, le asignemos a la variable el valor “null”
que indica que no hay ningún formulario “FrmEjemplo1” abierto */
instancia = null;
}
Probemos nuestra aplicación, repitamos los pasos descritos anteriormente y observaremos que ahora el
programa no falla.
Ahora codificaremos el formulario “FrmEjemplo2”. Damos doble clic en el ComboBox “cmbAlumnos” y
digitamos el siguiente código:
private void cmbAlumnos_SelectedIndexChanged(object sender, EventArgs e)
{
/* Definimos un objeto del tipo de formulario que queremos mostrar, pero ahora lo haremos
usando el método "GetInstancia" definido en el formulario "FrmEjemplo1" */
FrmEjemplo1 ejemplo1 = FrmEjemplo1.GetInstancia();
Hemos finalizado la codificación del ejemplo. Presionamos “F5” para probar el funcionamiento de nuestra
aplicación.
Observemos que, al seleccionar un alumno en el ComboBox, el formulario “FrmEjemplo2” se oculta y el
alumno seleccionado aparece en el TextBox “txtAlumno” del formulario “FrmEjemplo1”, que era lo que
necesitábamos hacer.
Guía 7 Ejemplo 3. Otro forma de crear una aplicación con formulario MDI, para definir formulario
padre y formulario hijo.
Creamos un nuevo proyecto Windows Forms y le colocamos como nombre “Guia7_Ejemplo3”. Como todo
proyecto de este tipo, nos agregará un formulario de nombre “Form1”, por el momento no haremos nada con
este formulario.
Procedemos a agregar un nuevo formulario. Damos clic derecho en el nombre del proyecto, en el menú
contextual seleccionamos la opción “Agregar”, en el nuevo menú contextual que aparece seleccionamos la
opción “Nuevo elemento…” como se observa en la siguiente figura:
En la ventana que aparece, seleccionamos “Windows Forms” y luego el tipo de elemento “Formulario
primario MDI” y le colocamos como nombre “FrmPrincipal” y damos clic al botón “Agregar”:
Programación I. Guía No. 7 17
Al realizar estos pasos nos cargará un nuevo formulario en nuestro proyecto con un aspecto muy distinto a los
formularios por defecto, tal como se observa en la siguiente figura:
Observamos que el formulario MDI se crea con un control MenuStrip y un control ToolStrip incluidos. En
estos controles, podemos modificar lo que deseemos, por ejemplo, eliminar o agregar opciones, eliminar o
agregar botones.
Le cambiamos la propiedad “Text” al formulario y le colocamos, por ejemplo: Formulario de ejemplo de uso
de MDI.
Podemos dar “F5” para ver como luce nuestro formulario MDI, sin olvidarnos cambiar en “Program.cs” que
cargue el formulario “FrmPrincipal”.
18 Programación I. Guía No. 7
Observemos que en unos pocos pasos hemos creado un formulario que contiene menús como los utilizados en
la mayoría de aplicativos de Microsoft.
Vamos a modificar un poco el formulario MDI creado en ejemplo 3. Trabajaremos con el formulario por
defecto “Form1” que nos aparece cuando creamos el proyecto. Cambiaremos su nombre a “FrmEditor”. Le
cambiamos la propiedad “Text” al formulario y le colocamos, por ejemplo: Editor de texto.
Añadimos un control TextBox, y modificaremos las siguientes propiedades:
Propiedad Valor
Name txtArchivo
Multiline true
Dock Fill
Figura 8.
Vamos a modificar el control MenuStrip en el formulario FrmPrincipal. Eliminamos las opciones: Editar,
Ver, Herramientas y Ayuda. Para eliminar una opción, la seleccionamos, damos clic derecho, en el menú
contextual que aparece, damos clic en la opción “Eliminar”, como se observa en la figura 9.
En la opción “Archivo” eliminamos las sub-opciones: Imprimir, Vista previa de impresión y Configurar
impresión. Agregaremos la opción “Cerrar ventana”.
Al final el formulario debe lucir parecido al que se muestra en la figura 10.
Programación I. Guía No. 7 19
Figura 9.
Figura 10.
Cuando pulsamos en la opción “Cerrar ventana” del menú “Archivo”, debemos averiguar cuál es el
formulario que actualmente tiene el foco, esto lo averiguamos usando la propiedad “ActiveMdiChild” del
formulario principal.
20 Programación I. Guía No. 7
Debido a que esa propiedad es del tipo Form, debemos hacer una conversión al tipo adecuado, en nuestro caso
del tipo “FrmEditor”.
Damos doble clic en la opción de menú “Cerrar ventana” y en el evento “Click” de esta opción colocamos el
siguiente código:
private void CerrarVentanatoolStripMenuItem1_Click(object sender, EventArgs e)
{
// Asignar la ventana que tiene el foco (que está seleccionada)
FrmEditor editor = (FrmEditor)this.ActiveMdiChild;
Modificaremos un poco los métodos Abrir y Guardar. Lo que debemos tener en cuenta es que cuando
seleccionemos el archivo que queremos abrir, tendremos que asignarlo al control TextBox del formulario hijo,
y cuando vayamos a guardar, usaremos ese contenido para grabarlo en el archivo que seleccionemos.
Pero aquí se nos presenta el mismo caso que a la hora de cerrar la ventana activa, debemos usar un código
parecido al que mostramos antes, ya que si no hay ningún formulario activo no deberíamos hacer nada de lo
que se supone que podemos hacer con esas dos opciones del menú.
Vamos a cambiar el resolutor de ámbito del TextBox “txtArchivo” de private a public, para que no de error el
código que colocaremos en el evento “Click” de la opción de menú “Abrir”. Seleccionamos en la ventana
“Explorador de soluciones” el archivo “FrmEditor.Designer.cs” y le damos doble clic, ubicamos la línea
generada automáticamente por el editor de Visual C#:
private System.Windows.Forms.TextBox txtArchivo;
Damos doble clic en la opción de menú “Abrir” y en el evento “Click” de esta opción colocamos el siguiente
código:
private void OpenFile(object sender, EventArgs e)
{
// Asignar la ventana que tiene el foco (que está seleccionada)
FrmEditor editor = ((FrmEditor)this.ActiveMdiChild);
// Cerramos el archivo
sr.Close();
}
}
}
Damos doble clic en la opción de menú “Guardar” y en el evento “Click” de esta opción colocamos el
siguiente código:
private void SaveAsToolStripMenuItem_Click(object sender, EventArgs e)
{
// Asignar la ventana que tiene el foco (que está seleccionada)
FrmEditor editor = ((FrmEditor)this.ActiveMdiChild);
// Cerramos el archivo
sw.Close();
}
}
}
El mismo código debe escribirse en el evento “Click” de la opción de menú “Guardar como”.
Tarea Complementaria
1. Investigar qué tipos de estructuras de datos puede gestionar una aplicación Windows Forms en Visual
C#.
2. Investigar las diferentes formas de conectar una base de datos a una aplicación Windows Forms en
Visual C#.
Bibliografía
❖ Deitel, Harvey M. y Paul J. Deitel, Cómo Programar en C#, Segunda Edición, México, 2007.
Anotaciones