Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO ¿Qué es Windows Forms? Forms? Cod. 1728.61 PLATAFORMA .NET Y SERVICIOS WEB Desarrollo de aplicaciones de ventana César Fernández Acebal acebal@ieee.org • Windows Forms es una biblioteca de clases que forma parte del Framework .NET • El Framework .NET está compuesto por una vasta colección de clases – Programación Web, XML, E/S, etcétera • Windows Forms proporciona casi todo lo necesario para desarrollar aplicaciones de ventanas Dpto. de Informática OOTLab OOTLab - Laboratorio de Tecnologías de Orientación a Objetos www.ootlab.uniovi.es Aplicaciones de ventanas Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO César F. Acebal – OOTLab OOTLab Programación para Windows Comparación y arquitectura Cómo programar aplicaciones para Windows Año de Lenguaje Interfaz aparición 1985 C API de Windows 1992 C++ Biblioteca MFC (Microsoft Foundation Class) Class) • La API de Windows era un conjunto inmanejable de funciones • MFC no tenía un buen diseño orientado a objetos • Windows Forms sí es completamente OO 2001 C#, C#, VB.NET, VB.NET, C++, etc. Windows Forms – Simplifica enormemente la programación de interfaces de usuario MFC • Libros: – Programming Windows, Windows, Charles Petzold – Programming Windows with MFC, MFC, Jeff Proise – Programming Applications for Microsoft Windows, Windows, Jeffrey Ritcher Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Windows Forms Windows API Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Herramientas de desarrollo ¿Qué veremos en este módulo? • Microsoft Visual Studio .NET incorpora un Diseñador de Windows Forms • Seguiremos un enfoque programático – Permite arrastrar y soltar controles de interfaz de usuario y genera el código por nosotros – Se verá cómo desarrollar aplicaciones de ventanas programando en C# • Sin utilizar el Diseñador de Windows Forms • Introducción a la programación de ventanas – Cuadros de diálogos y ventanas (forms (forms)) • Microsoft .NET Framework SDK • Algunas estructuras fundamentales – Compilador en línea de órdenes – Point, Point, Size, Size, Rectangle, Rectangle, Color… Color… • (Como el JDK de Java) • Controles padres e hijos – Un ejemplo usando botones • Desarrollo de aplicaciones MDI Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 1 Aplicaciones de consola y de ventanas • Al compilador hay que indicarle el tipo de aplicación que queremos generar Introducción Diferencia entre las aplicaciones de consola y de ventana, y uso de cuadros de diálogo para ilustrar la programación de Windows Forms con C# – En Visual Studio, en las propiedades de la solución – En el compilador de C#, C#, mediante el atributo target (puede abreviarse como “t”) “t”) /target:exe /target:winexe Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Aplicaciones de consola y de ventanas • En realidad, no hay mucha diferencia entre unas y otras – Sólo marca el “ejecutable” como de un tipo u otro – Y posteriormente el entorno en tiempo de ejecución consulta dicha marca para ver si tiene que crear una ventana de órdenes o no • Pero se puede compilar una aplicación de Windows Forms como aplicación de consola Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Cuadros de diálogo Utilizaremos la clase MessageBox para ver los rudimentos de la programación con Windows Forms Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Nuestro primer programa System.Windows.Forms • MessageBoxHelloWorld.cs • La clase MessageBox pertenece al espacio de nombres System.Windows.Forms • Podríamos usar la declaración class MessageBoxHelloWorld { public static void Main() Main() { System.Windows.Forms.MessageBox. System.Windows.Forms.MessageBox. Show(“¡Hola, mundo!”); } } Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab using System.Windows.Forms System.Windows.Forms; ; • Hay que incluir las referencias a las DLL – System.dll, System.dll, System.Windows.Forms.dll • En el SDK, esto se hace mediante el atributo reference (“r”) /r:System.dll,System.Windows.Forms.dll Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 2 System.Windows.Forms La clase MessageBox • Es un espacio de nombres gigantesco • • • – Unas 200 clases y 100 enumeraciones – 41 delegados – 7 interfaces – 4 estructuras Deriva directamente de Object No puede ser instanciada Sólo define un método estático Show – En 12 versiones sobrecargadas Algunas versiones del método Show DialogResult Show(string mensaje) DialogResult Show(string mensaje, string titulo) Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Enumeración MessageBoxButtons Enumeración MessageBoxButtons Miembro Valor OK 0 OKCancel 1 AbortRetryIgnore 2 YesNoCancel 3 YesNo 4 RetryCancel 5 Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Enumeración MessageBoxIcon Enumeración MessageBoxIcon Miembro Valor None 0x00 Error 0x10 Question 0x20 ... … Otra versión del método Show DialogResult Show(string Show(string, , string, string, MessageBoxButtons, MessageBoxButtons, MessageBoxIcon) MessageBoxIcon) Otra versión del método Show DialogResult Show(string Show(string, , string, string, MessageBoxButtons) MessageBoxButtons) Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Obtener el valor de retorno • Podemos saber qué botón pulsó el usuario en un cuadro de diálogo • Para ello, el método Show devuelve una enumeración DialogResult DialogResult result = MessageBox.Show(…); MessageBox.Show(…); if (result == DialogResult.Yes) DialogResult.Yes) { … } else if … Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Ventanas Introducción a la clase en la que se basan las aplicaciones hechas con Windows Form Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 3 La ventana Crear una ventana • En una aplicación Windows, todo se organiza en torno a ventanas • Ejemplo de programa que crea una ventana – Lo que en la programación tradicional para Windows era una ventana (window (window)) en el framework .NET se denomina form Barra de título Barra de menú Área cliente Borde Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO public class NewForm { public static void Main() Main() { new System.Windows.Forms.Form(); System.Windows.Forms.Form(); } } • Se podría haber usado using System.Windows.Forms System.Windows.Forms; ; Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Jerarquía de clases de Form Aplicaciones de ventanas Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO César F. Acebal – OOTLab OOTLab Jerarquía de clases de Form • El término control designa a todos los objetos de la interfaz de usuario Object Object MarshalByRefObject MarshalByRefObject – Botones, barras de desplazamiento, campos de texto, etc. Component Component • La clase Control implementa gran parte de la base necesaria para dichos objetos Control Control – Entrada de teclado y ratón, visualización… ScrollableControl ScrollableControl • ScrollableControl añade capacidad de desplazamiento • ContainerControl permite añadir hijos al control ContainerControl ContainerControl Form Form Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Problema del programa anterior • El constructor de Form sólo se crea la ventana, pero no la muestra – Al finalizar, ésta se destruye (GC) – ShowForm.cs César F. Acebal – OOTLab OOTLab Mostrar la ventana • Podemos emplear los siguientes métodos o propiedades de Control Algunos métodos de Control Método Descripción void Show() void Hide() Hide() • Veamos una segunda versión Aplicaciones de ventanas Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Vuelve visible a un control Vuelve invisible a un control Algunas propiedades de Control Propiedad Tipo form.Show(); form.Show(); bool Visible Accesibilidad get/ get/set • Da lo mismo uno que otro: – form.Show(); form.Show(); – form.Visible = true; true; Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 4 ¿Qué ocurre? Método Application.Run() Application.Run() • form.Show() form.Show() realmente está mostrando la ventana • Pero no vemos nada porque nada más mostrarse se acaba el programa y se destruye ésta • Para comprobarlo, usar un retardo • Necesitamos llamar al método Run de la clase Application – Espacio de nombres System.Threading – Thread.Sleep(2500) Thread.Sleep(2500) Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab – Espacio de nombres System.Windows.Forms – No puede ser instanciada – Todos sus miembros son estáticos • Ejemplo ... form.Visible = True; True; Application.Run(); Application.Run(); Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Resultado Forma correcta • Ahora sí podemos ver la ventana • Pero tenemos otro problema: • En lugar de eso, pasamos la ventana como parámetro del método Application.Run – El método Application.Run() Application.Run() nunca termina, aunque cerremos la ventana – Si fue compilado en modo consola, consola, no vemos el texto “Press any key to continue” en la ventana de órdenes • Podemos terminar el programa pulsando Ctrl + C – Si fue compilado como una aplicación Windows • Usar el Administrador de Tareas de Windows y matar el proceso Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Application.Run(form); Application.Run(form); • En este caso no es necesario llamar a Show – El método Application.Run la hace visible automáticamente • Al cerrar la ventana que se le pasa como parámetro, el método finaliza • Es este método quien de veras hace que una aplicación sea de Windows – Y no el modo en que compilemos nuestro programa Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Dos ventanas Algunas propiedades de ventanas • Ejemplo: TwoForms.cs • Si cerramos la segunda ventana, la primera no se ve afectada • Por el contrario, si cerramos la primera ventana, se cierran • Ejemplo: FormProperties.cs • En este ejemplo veremos algunas propiedades de las ventanas – Ancho, alto, color de fondo, estilo de borde, control sobre la maximización, posición inicial, tipo de cursor… • Hace uso de algunas clases definidas en el espacio de nombres System.Drawing – Por lo que hay que acordarse de incluir System.Drawing.dll en el proyecto Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 5 Heredar de Form Heredar de controles predefinidos Hasta ahora hemos usado la clase Form tal cual. Ahora veremos cómo podemos usar una clase propia que herede de ella. • Hemos visto cómo crear una ventana y modificar algunas de sus propiedades • Pero muchas veces necesitaremos heredar de Form, Form, en vez de simplemente crear una instancia suya • Ejemplo – InheritTheForm.cs Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Inicialización en el constructor ¿Qué ventajas tiene heredar? • Lo normal es que la inicialización de la ventana se haga en la propia clase heredada, a través de su constructor • Antes podíamos acceder a todas las propiedades y métodos públicos de Form • Ahora tenemos acceso también a algunos que están declarados como protegidos • Ejemplo: el método protegido OnPaint – Y no en el método Main – Ejemplo: – Podemos redefinirlo y así no tendremos que instalar “manualmente” nuestro propio manejador de eventos – Sólo tiene un único argumento: PaintEventArgs • InheritedFormWithConstructor.cs • Podemos usarlo para obtener un objeto Graphics Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Jerarquía de clases de los botones Object Object Controles padres e hijos MarshalByRefObject MarshalByRefObject Component Component Los controles pueden contener otros controles (que se dibujan en su interior). Entre ellos se dice que hay una relación padrepadre-hijo. Veremos un ejemplo que añade un botón a una ventana. Control Control ButtonBase ButtonBase Button Button CheckBox CheckBox RadioButton RadioButton Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 6 Un ejemplo sencillo Controles padres e hijos • SimpleButton.cs • Todo control debe tener un padre button.Parent = this; this; • La línea anterior hace que el botón sea un control hijo de la ventana (form (form)) actual • Un control sin padre no es visible • ¿Qué efecto tiene esta relación? – El control hijo aparece dentro del padre • Recortándolo si es necesario (si no cabe) – La posición del hijo es relativa a la esquina superior izquierda del área cliente del padre – El hijo hereda algunas propiedades del padre: • Font, Font, ForeColor y BackColor Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Posición y tamaño Evento Click • Todas las propiedades de posición y tamaño (como Location y Size) Size) están implementadas en la clase Control • Para los descendientes de Control distintos de Form, Form, normalmente ClientSize es igual a Size • Los controles se crean con un tamaño predeterminado • Así es como la ventana instala un manejador de eventos para el evento Click del botón: Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab button.Click += new EventHandler(ButtonOnClick); • Donde ButtonOnClick debe ser un método definido por la ventana que tenga la misma signatura que System.EventHandler – Puede llamarse como se quiera, aunque éste es un buen convenio: • <Identificador del objeto> + On + <nombre del evento> • El botón genera un evento Click cada vez que es pulsado Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Aplicaciones MDI Aplicaciones MDI (MultipleMultiple-Document Interface) Interface) Son las aplicaciones que permiten mostrar varias ventanas a la vez • Permiten mostrar múltiples documentos a la vez, cada uno en su propia ventana • Suelen tener un elemento de menú llamado “Ven “Ventana” – Permite cambiar entre las distintas ventanas abiertas Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 7 Crear una ventana MDI padre Crear una ventana MDI hija • Es la ventana (form (form)) que contiene todas las ventanas hijas (o “subventanas”) • Para crear una ventana de este tipo, basta poner su propiedad IsMdiContainer a true • Las guías de estilo de interfaces de usuario recomiendan crear un elemento de menú de primer nivel, llamado “Ven “Ventana” • En ella no hay que indicar nada • Se hará en el padre – Propiedad MdiList a true • En nuestro ejemplo, tendremos también un menú “Archivo” con las opciones “Nuevo” y “Cerrar” Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab – Crear un manejador de evento que cree una nueva ventana hija private void NewChildForm(object sender, sender, EventArgs e) { Form newChild = new ChildForm(); ChildForm(); newChild.MdiParent = this; this; newChild.Show(); newChild.Show(); } Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Ejercicio • Crear una aplicación MDI que pueda crear nuevas ventanas hijas • Menú de la ventana principal Menús – Archivo • Nuevo (Ctrl (Ctrl + U) • Salir – Ven Ventana • Que tenga una lista de todas las ventanas abiertas • En las hijas, poner un RichTextBox Veremos cómo crear los menús mediante programación, sin emplear el diseñador de menús de Visual Studio .NET – Que ocupe todo el área cliente (Dock (Dock)) Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Menú principal Jerarquía de clases de los menús • El menú principal es aquél que se sitúa entre la barra de título de la ventana y el área cliente de ésta • También existen los menús contextuales – Que aparecen cuando el usuario hace clic con el botón secundario del ratón • El menú principal está asociado a una ventana, mientras que los de contexto están asociados con un determinado control Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Object Object MarshalByRefObject MarshalByRefObject Component Component Menu abstract) abstract) Menu ((abstract) MainMenu MainMenu ContextMenu ContextMenu MenuItem MenuItem Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 8 Cómo determinar la ventana hija activa Propiedad ActiveMdiChild • Habrá ocasiones en las que interese proporcionar una orden que opere sobre el control que tenga el foco en la ventana hija activa • La propiedad ActiveMdiChild de Form permite saber cuál es la ventana hija activa – P. ej., ej., copiar el texto seleccionado • Dos cuestiones a resolver: – Determinar cuál es la ventana activa – Determinar cuál es el control de esa ventana que tiene el foco Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Form active = ActiveMdiChild; ActiveMdiChild; if (active != null) null) { ... // buscar el control que tenga el // foco y hacer lo que corresponda } Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Propiedad ActiveControl Ejercicio • Ejemplo: • Que se pueda cerrar la ventana activa // Recorre todos los controles de la ventana if (childForm.ActiveControl (childForm.ActiveControl is TextBox) TextBox) { TextBox textBox = (TextBox)childForm.ActiveControl; TextBox)childForm.ActiveControl; ... } Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab – Añadir una opción al menú Archivo Cerrar Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Organizar las ventanas Ejercicio • Muchas aplicaciones MDI tienen operaciones de menú como Cascada, Cascada, Horizontal, Horizontal, Vertical… Vertical… para organizar las ventanas hijas • Que se pueda cerrar la ventana activa – Añadir una opción al menú Archivo Cerrar Método LayoutMdi de Form private void LayoutMdi(MdiLayout value) value) • La enumeración MdiLayout define los cuatro posibles valores – ArrangeIcons, ArrangeIcons, Cascade, Cascade, TileHorizontal, TileHorizontal, TileVertical Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 9 Clase Clipboard • Definida en System.Windows.Forms • Está sellada (no se puede heredar de ella) y no tiene constructores públicos (no se puede instanciar) instanciar) • Sólo proporciona dos métodos estáticos: El portapapeles Cortar, copiar y pegar La clase Clipboard proporciona la funcionalidad básica para cortar, copiar y pegar datos, ya sea dentro de la propia aplicación o entre aplicaciones. Métodos estáticos de Clipboard void SetDataObject(object o) void SetDataObject(object o, bool remainAfterExit) remainAfterExit) IDataObject GetDataObject() GetDataObject() Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Interfaz IDataObject Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Tipos de datos. Clase DataFormats Algunos de los métodos de IDataObject • Almacena los nombres de los tipos de datos predefinidos del portapapeles bool GetDataPresent(Type type) type) object GetData(Type type) type) • El primero nos permite consultar si los datos del portapapeles son de un determinado tipo data.GetData(DataFormats.Text) data.GetData(DataFormats.Text) data.GetDataPresent(typeof(String)) data.GetDataPresent(typeof(String)) • Con el segundo, se accede a dichos datos string s = (string (string) string) data.GetData(typeof(String)); data.GetData(typeof(String)); Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab Bibliografía • Programming Microsoft Windows With C# – Charles Petzold, Petzold, Microsoft Press, Press, 2002 Cursos de Verano 2002 UNIVERSIDAD DE OVIEDO WEB362 Aplicaciones de ventanas César F. Acebal – OOTLab OOTLab 10