Autor Tema: Dictado del Curso de C# (Deitel)

0 Usuarios y 1 Visitante están viendo este tema.

15 Febrero, 2010, 07:55 am
Respuesta #20

argentinator

  • Consultar la FIRMAPEDIA
  • Administrador
  • Mensajes: 7,274
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
  • Vean mis posts activos en mi página personal
    • Mis posts activos (click aquí)
Tutorial GUI con SWF para el capítulo 3 (parte 2).

Siempre que llovió paró.

Todo programa que comienza, tiene que terminar.
Esa es la gran ley de la programación.
Si no, es que el programa está mal hecho.

Lo que haremos será continuar con el programa del post anterior, y le iremos agregando cosas.
Lo primero que deseamos es ponerle un sencillo botón que permita salir del programa normalmente con un click del usuario.

Ése será nuestro objetivo. Ocurre que no es tan simple como uno quisiera.
Pero una vez que lo pongamos en práctica veremos que es muy sencillo a fuerza de acostumbrarnos a hacer siempre lo mismo.

Los pasos necesarios para poner un botón en la ventana de nuestra aplicación son los siguientes:

  • Dentro de nuestra clase Formulario tenemos que declarar una variable de tipo Button.
    El tipo de datos Button está predefinido en las librerías de System.Windows.Forms, así que no nos preocupemos por los detalles.

    Basta conque agreguemos una línea como esta a nuestro programa:


        private Button XXXX;


    Le hemos puesto el nombre XXXX porque todavía no sabemos bien qué haremos con el susodicho botón.
    En realidad, como hemos dicho, lo utilizaremos para finalizar la aplicación.
    Así que un nombre adecuado sería algo como TerminarPrograma.

    Al agregar esta declaración no se ha hecho realmente nada nuevo.
    El programa no tendrá ningún efecto, no se verá botón alguno.
    ¿Y entonces para qué?

    Bueno, digamos a grandes rasgos que cada elemento que agregamos a la ventana de la aplicación requiere espacio en la memoria de la computadora.
    Se trata de un objeto que vivirá en memoria por un tiempo.
    Ese espacio se crea con una sentencia new.
    Bastaría escribir algo como new Button; y fin del problema.

    Sin embargo, para poder hacer modificaciones o retoques posteriores, sería bueno tener alojado este objeto en una variable accesible todo el tiempo, con un nombre concreto.
    Esa variable es lo que hemos declarado en este ítem.
    En ella se puede albergar a partir de ahora cualquier objeto del tipo Button.

    Para ver exactamente dónde se coloca la declaración, y cómo queda el código hasta ahora, abrir el desplegable:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
              ClientSize = new Size(300, 600); 
        }

    }


    [cerrar]

  • Ahora queremos crear un objeto de tipo botón, y asignarle espacio en memoria. Esto se hace mediante una declaración new Button().
    Sin embargo, este objeto lo asignaremos además a la variable declarada en el ítem precedente, así que pondremos la sentencia:


            TerminarPrograma = new Button();


    Veamos cómo luce esto dentro de nuestro programa:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

             ClientSize = new Size(300, 600); 
        }

    }


    [cerrar]

  • El siguiente paso es "maquillar" el botón, vale decir, configurarlo para que tenga el aspecto y características deseadas.
    Los objetos de clase Button, así como cualquier otro widget, disponen de muchísimos atributos que se pueden modificar.
    No es necesario que los aprendamos a todos de memoria, tan sólo iremos usando de a poco los más comunes.

    Deseamos que tenga un tamaño de 22 pixels de alto. Esto se logra modificando el atributo Height, mediante una sentencia como esta:


            TerminarPrograma.Height = 22;


    Además quisiéramos que contenga la leyenda de texto "Terminar Programa". Para ello se asigna el atributo Text, así:


            TerminarPrograma.Text = "Terminar Programa";


    Nos preguntamos si esa leyenda cabrá o no en el espacio que ocupa el botón en pantalla.
    Eso depende del ancho y alto del mismo.
    No queremos variar el alto, así que tendremos que poner una anchura adecuada para que quepa toda la frase. Ensayamos con 120 pixels de ancho. El atributo que debe modificarse es Width, con esta sentencia:


            TerminarPrograma.Width = 120;


    Si dejamos las cosas como están, el botón aparecerá en el rincón superior izquierdo de la ventana de la aplicación.
    Quisiéramos controlar su ubicación en la ventana, poniéndolo más o menos en el centro de ella.
    Como nuestra ventana era de 300x600, para centrarlo tendríamos que colocarlo en la posición (150, 300).

    Las coordenadas que se usan para los widgets son relativas a la ventana de la aplicación en que aparecen. El origen (0, 0) de coordenadas es el extremo superior izquierdo de la ventana, y se avanza de izquierda a derecha con la primer coordenada (o coordenada horizontal, o abscisa), y de arriba hacia abajo con la segunda coordenada (o coordenada vertical, u ordenada).

    Con estas convenciones, y sabiendo que el atributo a modificar ha de ser Location, usaremos una sentencia como ésta para lograr nuestro propósito:


            TerminarPrograma.Location = new Point(150,300);


    Observe que hemos tenido que usar el tipo de datos Point que está declarado en la librería System.Drawing.
    Esa es la manera correcta de darle un valor al atributo Location.
    No entremos en detalles sobre ello, y simplemente copiémoslo así por ahora.

    El resultado de agregar todas esas sentencias a nuestro programa es el código que se muestra en el desplegable que sigue:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(150,300);


             ClientSize = new Size(300, 600); 
        }

    }


    [cerrar]

  • Lo que hemos logrado es asignar espacio en memoria para el botón, y también lo hemos configurado a nuestro gusto.
    Pero si ejecutamos el programa tal como está hasta el momento, el botón no aparecerá en la ventana de la aplicación. ¿Por qué?  :banghead:  :banghead:

    Bueno, la razón es que falta que hagamos algo: enlazar el botón a la ventana.
    Esta acción es necesario realizarla siempre explícitamente, porque una aplicación compleja podría tener varias ventanas, y habría que especificar a cuál pertenece nuestro botón.
    Aún así, por alguna razón puede preferirse que quede oculto hasta cierto momento, así que una buena forma de mantenerlo invisible sería, "dejarlo sin atar a la ventana".

    ¿Cómo se le dice a la ventana de la aplicación que el botón que hemos creado y configurado le pertenece a ella, y que debe mostrarlo?
    Debemos invocar al método Constrols.Add(), el cual está definido para todo objeto de tipo Form, y en particular para nuestra ventana de aplicación, que es de tipo Formulario, que a su vez hereda los atributos de Form...

    La sentencia que se debe escribir tiene un formato muy entendible, y es así:


            Controls.Add( TerminarPrograma );


    Le estamos diciendo a la ventana de la aplicación que se agregue a sí misma el widget alojado en la variable TerminarPrograma.
    Veamos el aspecto del programa con esta nueva línea de código:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(150,300);

             // Agregar widget a la ventana
             Controls.Add(TerminarPrograma);


             ClientSize = new Size(300, 600); 
        }

    }


    [cerrar]

  • Si ahora ejecutamos la aplicación veremos que el bendito botón por fin aparece, tal como lo hemos estipulado.
    Sin embargo, vemos que aparece "descentrado" en la ventana.
    Esto se debe a que las coordenadas del botón se refieren a su esquina superior izquierda.


    Para poder centrarlo será necesario hacer corrimientos hacia la izquierda y hacia arriba, restando la mitad del tamaño del botón. O sea que en la línea del atributo Location introducimos una modificación:


            TerminarPrograma.Location = new Point(90,289);


    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(90, 289);

             // Agregar widget a la ventana
             Controls.Add(TerminarPrograma);

             ClientSize = new Size(300, 600); 
        }

    }


    [cerrar]

  • Ahora el programa tiene el aspecto que deseábamos:


    Sin embargo, al hacer click sobre el botón que alegremente dice "Terminar Programa", vemos que no se produce ningún efecto.
    Esto es así porque no hay manera de que la computadora adivine nuestra intención de que el botón tiene que reaccionar de determinada manera al presionarlo.
    Habrá que indicárselo explícitamente.

    Lo que queremos es que reaccione ante un click del usuario.
    El click del ratón, se considera un evento.
    Puede haber muchas clases de eventos, y no entraremos por ahora en más detalles.
    Sólo tengamos en cuenta aquellos eventos que provienen de la acción directa del usuario, en este caso, hacer click con el ratón.

    Ante esto se espera una reacción, vale decir manejar el evento realizando alguna acción pertinente.
    Se requiere que uno defina un método que sirva de manejador del evento.

    Los manejadores de eventos tienen ciertas características especiales, que nosotros por ahora vamos a repetir como loros sin indagar en profundidad qué significan.
    Nuestro manejador del evento click sobre el botón TerminarPrograma se llamará AccionClickBoton_TerminarPrograma.
    Es un nombre muy largo... es cierto, pero es muy descriptivo, y nos evitará confusiones en el futuro.

    El método tiene en su encabezado varias "palabrejas" y "argumentos" asociados.
    No nos preocupemos por todo eso.
    Lo importante es que lo especifiquemos en el lugar correcto del código, a saber: dentro de la clase que hemos llamado Formulario.

    El manejador se escribe así:


        private void AccionClickBoton_TerminarPrograma(object sender, EventArgs e)
        {

        }


    Entre las llaves {  ...  } tendremos que poner todas las acciones que queremos que el programa realice al "dispararse" el evento.

    Ni se nos ocurra preguntar qué significan las palabras "void", "object", "sender", "EventArgs"...
    No tenemos que preocuparnos por eso ahora. ¡No!

    El código completo luce como se muestra aquí:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(90, 289);

             // Agregar widget a la ventana
             Controls.Add(TerminarPrograma);

             ClientSize = new Size(300, 600); 
        }

        private void AccionClickBoton_TerminarPrograma(object sender, EventArgs e)
        {

        }



    }

    [cerrar]

  • Obviamente, como el manejador de eventos se ha declarado, pero no se le han puesto "acciones" a realizar, cuando hagamos click sobre el botón seguiremos sin tener efecto alguno.

    Las acciones a realizar dependen ahora de nuestro libre albedrío.

    Deseamos que la acción a ejecutarse sea la de "Terminar con la aplicación".
    ¿Como se indica esto?
    Bueno, para terminar correctamente una aplicación GUI con System.Windows.Forms tenemos que llamar al método Application.Exit().
    Nuestro manejador tendrá ahora este aspecto:


        private void AccionClickBoton_TerminarPrograma(object sender, EventArgs e)
        {
            Application.Exit();
        }


    Como se ve, la programación de las acciones en este caso ha sido muy sencilla.
    Se ejecuta una sola acción, y listo. Eso es todo el manejador de eventos en este caso.

    Estado del programa hasta el momento



    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(90, 289);

             // Agregar widget a la ventana
             Controls.Add(TerminarPrograma);

             ClientSize = new Size(300, 600); 
        }

        private void AccionClickBoton_TerminarPrograma(object sender, EventArgs e)
        {
            Application.Exit();
        }

    }


    [cerrar]

  • Sin embargo, cuando corremos el programa, vemos que el botón ¡¡¡sigue sin reaccionar!!!  :banghead:

    ¿Qué es lo que falta?
    Hemos dicho antes que no sólo hay que definir el manejador de un evento, sino que también hay que enlazarlo o atarlo el evento en cuestión.
    Debemos indicarle al programa que "enlace" el evento de hacer click sobre el botón TerminarPrograma al manejador AccionClickBoton_TerminarPrograma().
    ¿Cómo se hace esto? Con esta línea:


            TerminarPrograma.Click += new EventHandler( AccionClickBoton_TerminarPrograma );


    En esa línea lo que se ha hecho es crear un nuevo manejador de eventos (new EventHandler), al cual se le ha indicado entre paréntesis el método que se ha de llamar ante la ocurrencia del evento Click.

    Debemos pensar en esta sentencia como si fuera la asignación o modificación de un atributo más, como cualquier otro, del botón TerminarPrograma.
    Así que lo agregamos a la lista de asignaciones de atributos que ya teníamos en el constructor de Formulario(), y nos queda el siguiente código:

    Estado del programa hasta el momento

    using System;
    using System.Windows.Forms;
    using System.Drawing;

    static class Aplicacion_Vacia
    {
        static void Main()
        {
            Application.Run(new Formulario());
        }
    }

    // Clase para definir Formulario de aplicación:

    public class Formulario : Form
    {

        private Button TerminarPrograma;

        public Formulario()
        {
             TerminarPrograma = new Button();

            // Atributos de "TerminarPrograma"
            TerminarPrograma = new Button();
            TerminarPrograma.Height = 22;
            TerminarPrograma.Text = "Terminar Programa";
            TerminarPrograma.Width = 120;
            TerminarPrograma.Location = new Point(90, 289);

           TerminarPrograma.Click += new EventHandler(AccionClickBoton_TerminarPrograma);


             // Agregar widget a la ventana
             Controls.Add(TerminarPrograma);

             ClientSize = new Size(300, 600); 
        }

        private void AccionClickBoton_TerminarPrograma(object sender, EventArgs e)
        {
            Application.Exit();
        }

    }

    [cerrar]

  • Recordemos guardar todo el proyecto (Archivo/Guardar Todo).

    Ahora sí, al correr el programa, y hacer click en el botón, veremos cómo felizmente se realiza la acción de "terminar la aplicación", como deseábamos.




A continuación, agregaremos más información y funcionalidades a nuestro programa, así como etiquetas informativas.