Issuu on Google+

TRABAJO CON PROYECTOS VISUALES EN C# Un proyecto visual en C# se crea como una ‘Windows Application’, de la siguiente manera:

Como normas fundamentales de planificación de un proyecto, vemos unos cuantos detalles a la hora de generar un proyecto de este tipo (y de otros): ?

Siempre hay que poner la solución en un sitio conocido y adecuado, no en el sitio por defecto que propone el entorno.

?

No hay que dejar los nombres por defecto, tales como Solution1, Application1, etc. Cuando tengamos varios proyectos no habrá manera de identificarlos con las carpetas ni con sus nombres, y todos parecerán iguales.

?

No es buena idea meter en la misma carpeta la solution y el project. Hay que generar una carpeta independiente para el proyecto, dentro de la carpeta de la solución. Lo más normal es que una solution tenga varios proyectos, y que uno de ellos comparta el sitio con ella, sea cual sea, no es lo más indicado.

?

En general, cuando se dan de alta elementos de un proyecto o una solution mediante los asistentes, hay que poner nombres a todo, porque si no, luego cuesta mucho más el cambiarlos una vez que se han generado.


Una vez generada la solution y el proyecto, tendremos una pantalla como la siguiente:

Lo primero que hemos de hacer es dar un nombre adecuado al formulario. No es bueno que los formularios de un proyecto se llamen Form1, Form2, etc. Hemos de cambiar su nombre (propiedad (name), tal como se ve en la pantalla anterior). Hemos de cambiar el nombre del fichero donde se va a guardar. En este caso, el formulario se va a llamar Principal, y su fichero será Principal.cs Hay que cambiar un pequeño detalle en el código:

Hay que cambiar el new Form1() por un new Principal, ya que hemos cambiado el nombre al formulario. Es importante hacer estas tareas al principio, antes de todo lo demás, porque si no, luego tendremos un montón de funciones con nombre que hacen referencia a Form1, y será mucho más complicado.


Ahora estamos en disposición de ver como funciona nuestro proyecto. Ejecutándolo, aparecerá un programa totalmente vacío:

Para cambiar la vista de edición entre el diseño del formulario y el código, en la ventana de la solucion tenemos los siguientes botones:

Vista de diseño del formulario Vista de código

Propiedades del formulario Hay un conjunto de propiedades que se pueden establecer durante el diseño del mismo, es decir, sin escribir código: Las propiedades del intuitivas, en general.

formulario

son

bastante

La que se usan más normalmente son las siguientes: Name FormBorderStyle GridSize Icon MaximizeBox MinimizeBox Size StartPosition Text WindowState

Name Es el nombre del formulario. Todo formulario tiene que tener un nombre decente, no Form1, o Form2, hay que cambiarlo siempre.


FormBorderStyle Es el estilo del borde del formulario. Los valores más usados son: - Sizeable: El usuario puede cambiar el tamaño del formulario durante la ejecución del programa. - FixedDialog: El tamaño del formulario en ejecución es fijo, no se puede modificar. En general, no se debe dejar como sizeable un formulario que no resizee su interior convenientemente al cambiar de tamaño, da muy mala imagen y sensación de dejadez y poca profesionalidad. GridSize Es el tamaño de separación entre los puntitos que aparecen en tiempo de diseño y que valen para colocar alineados los componentes dentro del formulario. Normalmente, un valor de 4x4 es mucho más adecuado que el de 8x8 que aparece por defecto. Icon Es el icono del formulario (dibujito superior izquierdo). En un proyecto solo ha de tener icono el formulario principal, o bien los formularios MDIChild si es un proyecto MDI. En el resto de formularios hay que quitar el icono, queda muy feo un formulario de interacción con el usuario con un dibujo por defecto que no vale para nada. MaximizeBox MinimizeBox Sirven para hacer aparecer o desaparecer los botones de maximizado y minimizado en el borde superior derecho de la pantalla. En un formulario fijo, estos botones se han de quitar, no pintan nada y hace muy feo que queden alli. Size Define el tamaño del formulario. Normalmente es mejor ajustar su tamaño estirandolo directamente con el raton, pero si queremos que mida algo exacto, se pueden fijar en esta propiedad los valores. StartPosition Dice la posición del formulario con respecto a la pantalla y al formulario que lo activa. Por defecto, esta propiedad vale WindowsDefaultLocation. No se debe dejar así. Los valores adecuados son: - CenterScreen: El formulario aparece centrado en la pantalla - CenterParent: El formulario aparece centrado en el que lo activó. Text Es el texto del titulo del formulario WindowState Para formularios sizeables, esta propiedad permite decidir si el formulario aparecerá de alguna de las siguientes maneras: - Normal: En el tamaño en que ha sido dibujado - Maximized: Ocupando toda la pantalla del ordenata. - Minimized: Iconizado en la barra de tareas. Existen propiedades de aspecto del formulario, tales como: -

BackColor BackgroundImage ForeColor Font Opacity TransparencyKey TopMost

Estas propiedades son muy majas de probar (fuentes, colores, etc). Sin embargo no deben ser cambiadas a no se que se quiera indicar algo muy importante con ese cambio. Las pantallas de un programa han de ser lo más estándar posible, no deben ser de color rosa, con fuentes raras, ni nada semejante. Este tipo de cambios exigen una gran coherencia de imagen en todo el proyecto, y normalmente lo mejor es dejar la apariencia tal cual.


Eventos del formulario Los eventos son señales lanzadas por el formulario en tiempo de ejecución, las cuales podemos capturar y definir el código que se ejecutará cuando ocurran: Los que se usan más normalmente son los siguientes: Load Activated Deactivate Closed Closing Click DoubleClick KeyUp KeyDown KeyPress MouseUp MouseDown MouseMove Paint Resize

Load Activated Deactivate Closed Closing Son eventos que se lanzan al cargar se formulario, al cargarse los controles y activarse, al perder el foco de activación, y al descargarse. Veremos mas adelante un ejemplo de su uso, con un formulario hijo activado específicamente. Click DoubleClick MouseMove MouseUp MouseDown Son eventos que se lanzan al mover el ratón o pulsar los botones del mismo. KeyUp KeyDown KeyPress Son eventos que se lanzan al pulsar teclas en el teclado. (Atención a la propiedad KeyPreview). Paint Evento lanzado cuando el formulario es repintado por el sistema operativo (estaba debajo de alguna otra cosa, adquiere visibilidad y debe ser redibujado). Rezise Evento lanzado cuando el formulario cambia de tamaño.


Ejemplo de atención a un evento del formulario. Vamos a hacer que en la barra del titulo del formulario, en todo momento, figure la posición donde se encuentra el ratón. ?

Primero hemos de atender el evento MouseMove, que es el que se produce cuando el ratón cambia de sitio.

Hemos hecho doble click sobre el evento que queremos atender, y ha aparecido automáticamente la función que se ejecutará cuando se produzca ese evento. Dentro de la función, hemos escrito this.Text = e.X + “,” + e.Y; que coloca en la propiedad Text del formulario la coordenada X y la coordenada Y separado por una coma. El argumento e (de tipo System.Windows.Forms.MouseEventArgs) contiene las propiedades actuales del ratón, entre las que están la X y la Y, que son las que hemos utilizado.

Si abrimos el codigo manejado por el diseñador del formulario, tenemos lo siguiente:

Aquí podemos ver que todas las propieadades que hemos establecido en tiempo de diseño, realmente han sido codificadas dentro del programa por el diseñador de formularios. En la ultima linea, podemos ver como se añade el delegado Principal_MouseMove a la gestion de eventos de MouseMove del formulario, que es la que realmente codifica la gestion del evento. this.MouseMove es un array de punteros a funciones, que serán llamadas cuando se produzca el evento. Tiene sobrecargado el operador +, que permite añadir funciones a este array. Si queremos eliminar la atención de este evento, deberemos eliminar esta linea del InitializeComponent, y luego borrar la funcion Principal_MouseMove. Una alternativa es posicionarnos en el evento (en el diseño del formulario), hacer botón derecho, y escoger Reset. Esto elimina la agregación del delegado, pero todavía deberemos eliminar manualmente la función Principal_MouseMove.


En tiempo de ejecuci贸n nuestro programa ahora ser铆a el siguiente (vemos como en la barra de t铆tulo aparecen las coordenadas del rat贸n en el momento actual):


INSERCION DE COMPONENTES DENTRO DE UN FORMULARIO Veremos ahora como insertar y utilizar los componentes más normales, los más sencillos.

Inserción de un menú

Menu, una vez elaborado Componente de tipo Menu Hemos añadido un menú al programa (seleccionar el componente, y hacer click en medio del formulario). Le hemos dado un nombre (en este caso MenuPrincipal). Hemos tecleado las opciones del menú (es bastante intuitivo, type here, …). Le hemos dado nombre a las opciones que vamos a utilizar del menú (Hacer Algo -> MNU_HacerAlgo, Salir -> MNU_Salir). Para meter un separador en el menú, hay que insertar un elemento y ponerle como texto un guión. Ahora atendemos los eventos del menú MNU_HacerAlgo, y del MNU_Salir, tal como se ha explicado en el caso del formulario. Hay que tener en cuenta que las propiedades y eventos que aparecen en la parte derecha del diseñador corresponden al objeto que esta seleccionado.


Vemos que la opción de menú hacer algo nos da un mensaje (observar la llamada a MessageBox.Show), y que el menú Salir termina la ejecución del formulario (invoca al método Close ()).

Hay que tener cuidado y dar nombres razonables a todos los elementos de menú que vayan a ser utilizados como generadores de eventos. No se deben dejar elementos como MenuItem1, ni cosas por el estilo, porque después es muy complicado ver que hace un programa y entenderlo.


Inserción de una etiqueta

Componente de tipo Label Hemos insertado una etiqueta en el formulario. Le hemos puesto de nombre UnaEtiqueta, y en la propiedad Text Esto es el titulo de la etiqueta. Una etiqueta se usa básicamente para dos cosas: -

Para poner un titulo en el formulario, sin más. Para definir un área donde se mostrarán datos de solo lectura al usuario.

Si la etiqueta se va a usar para mostrar información al usuario, se le debe cambiar el nombre. No es bueno encontrar en el programa cosas del estilo: Label1.Text = Información, por ejemplo. Las propiedades de la etiqueta son bastante intuitivas, comentaremos las más importantes y más comúnmente usadas: AutoSize BorderStyle TextAlign

Permite definir si la etiqueta ha de ajustar su tamaño automáticamente. Permite definr el aspecto del borde de la etiqueta Definición del alineado del contenido de la etiqueta.


Inserción de un botón

Componente de tipo Button (botón) La propiedad más importante del botón es Text, que es el texto que aparece dentro del mismo. Atención del evento Click del botón: En este caso, al pulsar el botón, escribimos en la etiqueta anterior ‘Hola que tal’.


Inserción de una caja de texto

Componente de tipo TextBox (caja de texto) Una caja de texto se utiliza para que el usuario teclee datos que el programa usará después (una especie de scanf, mas o menos). La propiedad más importante es Text, que es el contenido de la caja de texto. Se le pueden asignar cosas o consultar su valor. Vamos a modificar el evento click del botón, para que al pulsarlo haga que el la etiqueta salga lo que hay escrito en la caja de texto:


Un programa muy sencillo, se puede construir básicamente con etiquetas, botones y cajas de texto (el menú ya sería algo “sofisticado”). El resto de controles no los vamos a comentar en este momento, muchos de ellos son muy intuitivos y solo hay que probar su funcionamiento, otros, son mas complicados, y seguramente exigirán buscar información sobre ellos. Generalmente, no hay más que escribir en el Google lo que uno busca, y aparecen cosas hasta de debajo de las piedras:

Sin embargo, muchas veces es necesario “pintar” dentro del formulario, visualizar gráficas, datos en forma de matriz, etc. Vamos a ver ahora un par de técnicas para conseguir esto: -

Por un lado, utilizaremos un panel para dibujar físicamente en su interior. Por otro lado, utilizaremos el control dbGrid, que es una matriz de visualización de datos.


Dibujar dentro de un panel Vamos a insertar un panel y un botón en el formulario:

Control de tipo Panel Al panel lo hemos llamado Dibujo, y al botón Dibujar. En el evento click del botón dibujar, escribimos lo siguiente:

Hemos hecho lo siguiente: ?

Obtener un objeto de tipo System.Drawing.Graphics para poder dibujar en él. No se puede dibujar directamente en el panel, hace falta el contexto que devuelve su método CreateGraphics, para hacerlo dentro de él.

?

Para dibujar una línea es necesario definir un Lápiz (se puede reutilizar luego, por supuesto), y utilizar el método DrawLine del objeto Graphics.

?

Para dibujar texto hace falta definir una fuente, una brocha, y utilizar el método DrawString.

?

Para dibujar un rectángulo, hace falta un lápiz, y utilizar el método DrawRectangle.

La clase Graphics tiene muchísimas llamadas, es cuestión de consultarla para ver más posibilidades.


El aspecto en ejecución de este programa, una vez pulsado el botón, será el siguiente:

Sin embargo, ocurre una desgracia irreparable… Cuando ocultamos el formulario (poniendo otro encima, cambiando de tarea), al volver a visualizarlo el dibujo ha desaparecido. Esto ocurre porque Windows no guarda el contenido de cada ventana cuando deja de estar en el “topmost” de pantalla. Si hiciera esto, debería guardar, por ejemplo, para esta ventana, unos 600 x 400 puntos, esto es 240.000, cada punto ocuparía 4 bytes, o sea, casi una mega. Se ve que es inviable, si cada pantalla ocupara una mega de memoria solo para guardar el dibujito, el sistema se colapsaría rápidamente, al activar varios programas. Por tanto, Windows lanza un evento Paint cuando un control debe ser repintado, por pasar a estar visible una parte que había estado oculta anteriormente. La técnica de un programa es entonces un poco más estructurada: No se puede pintar directamente en pantalla (a menos que no nos importe que se pierda la información al ocultarse), sino que se ha de crear una estructura de datos con la información a pintar, y dentro del evento Paint realizar el dibujo de la misma. Se puede provocar un repintado invocando al método Invalidate.

Hemos cambiado un poco el código: -

El objeto Graphics, para pintar, ya está disponible en el argumento e que llega al evento paint. El texto que se pinta es el contenido de la caja, para ver como realmente cambia.

Ahora, en el Paint se realiza el trabajo de dibujar, y en el botón simplemente se llama a Invalidate, para provocar un evento de este tipo. Cuando el programa se inicia, ya aparece pintada la información, porque se produce un evento Paint justo al dibujarse el control.


Como utilizar una DataGrid para cargar informaci贸n.

Componente DataGrid Para esta prueba se ha a帽adido al proyecto una clase Cliente: using System; namespace EjemploV { public class Cliente { private int m_Codigo; private string m_Nombre; public Cliente(int Codigo,string Nombre) { m_Codigo = Codigo; m_Nombre = Nombre; } public int Codigo { get { return m_Codigo; } set { m_Codigo = value; } } public string Nombre { get { return m_Nombre; } set { m_Nombre = value; } } } }


El c贸digo asociado al primer bot贸n (Grid) es el siguiente:

Se puede ver como asocia al datagrid (propiedad DataSource) un DataTable, que contiene la informaci贸n a mostrar. Es decir, se trata de crear un DataTable, con sus DataColumn correspondientes, y luego asignarlo al DataSource del DataGrid para que lo visualice. Al crear un DataColumn se le ha de indicar el nombre de la columna y el tipo de dato (en este caso son todas string). Las propiedades adicionales (PreferredColumnWidth, etc) son para visualizar mejor la informaci贸n.


El c贸digo asociado al segundo bot贸n (Grid2) es el siguiente:

En este caso, se le asigna al DataGrid un ArrayList, donde cada elemento es de tipo Cliente. La grid muestra en cada fila un elemento del ArrayList, cada uno con sus datos asociados.


El uso mas habitual de un datagrid est谩 enfocado a utilizar bases de datos. Por ejemplo, esta seria la forma de mostrar una consulta sobre una grid: private void Consultar_Click(object sender, System.EventArgs e) { SqlConnection Cnx; Cnx = new SqlConnection("server=localhost;uid=pepe;pwd=pepe;database=Musika"); Cnx.Open(); SqlDataAdapter Adp; Adp = new SqlDataAdapter("SELECT * FROM Grupos WHERE GRP_Nombre LIKE 'K%'", Cnx); DataSet Dt = new DataSet(); Adp.Fill(Dt, "Grupos"); Cnx.Close(); G.DataSource = Dt; G.DataMember = "Grupos"; G.Refresh (); }

Este programa crea una conexi贸n con una base de datos en SqlServer (Musika). Crea una consulta sobre la tabla Grupos, buscando los que tengan el nombre empezando por K. Crea un DataSet y lo llena con la consulta. Enlaza este DataSet con la Grid, y como se puede ver, aparecen los resultados.


Uso del control OpenFileDialog / SaveFileDialog Este control sirve para abrir la ventana estandar de Windows y pedir al usuario que escoja un archivo: private void Abrir_Click(object sender, System.EventArgs e) { DlgAbrir.Filter = "Pedeefes|*.pdf|" + "Textos|*.txt|" + "Documentos|*.doc|" + "Imagenes|*.bmp;*.jpg;*.gif|" + "Todos los archivos|*.*"; DlgAbrir.InitialDirectory = "C:\\Kastefa\\LPII (2004-2005 Q1)"; DlgAbrir.Title = "Abrir unas cosas"; if (DlgAbrir.ShowDialog () == DialogResult.OK) { lbAbrir.Text = DlgAbrir.FileName; } }

La propiedad Filter (optativa, por defecto muestra todos los archivos) llena el combo inferior (Tipo), y sirve para filtrar determinadas extensiones y mostrar una leyenda adecuada. La propiedad Title (optativa, por defecto muestra ‘Abrir’), sirve para cambiar el titulo del diálogo. La propiedad InitialDirectory sirve para establecer el directorio en el que se abre el dialogo. Devuelve DialogResult.OK si se pulsó Abrir, DialogResult.Cancel si se pulsó Cancelar. La propiedad FileName contiene el nombre del archivo con la ruta completa. La propiedad FileTitle contiene el nombre del archivo, sin el path.


Una vez aceptado el di谩logo, se puede ver el nombre del archivo en la etiqueta inferior:

El c贸digo asociado al bot贸n Guardar ser铆a el siguiente: private void Guardar_Click(object sender, System.EventArgs e) { DlgSalvar.FileName = lbAbrir.Text; if (DlgSalvar.ShowDialog() == DialogResult.OK) lbAbrir.Text = "Se ha escogido salvar"; else lbAbrir.Text = "Se ha escogido no salvar"; }


Uso del control Timer Este control sirve para provocar eventos temporales, cada cierto tiempo.

Control Timer Le hemos llamado Temporizador, como nombre del objeto insertado. Sus propiedades más importantes son: Enabled Interval

Indica si funciona o no funciona. (Envia eventos o no lo hace) Tiempo entre evento y evento, en milisegundos.

En el formulario se ha puesto un botón Tiempo, que lo habilita y lo deshabilita, y una etiqueta para ver la fecha/hora actuales, refrescada en cada evento del temporizador: private void Tiempo_Click(object sender, System.EventArgs e) { Temporizador.Enabled = !Temporizador.Enabled; Temporizador.Interval = 1000; } private void Temporizador_Tick(object sender, System.EventArgs e) { lbTiempo.Text = DateTime.Now.ToString(); }

El evento Tick del Timer es el que se envía cada vez que vence la cuenta.


Proyecto en Visual C#