Eventos y Señales - Manejando el curso de nuestra aplicación

El programar interfaces gráficas es sólo eso, dibujar una interfaz, no es crear la aplicación como tal. Por ello es que hace falta algo ... sí, métodos que puedan hacer que interactuen nuestros widgets ( todo aquel objeto gráfico ) entre sí.

Llamamos evento, a la acción sucedida a un widget ( presionada, cerrada, etc ). Cada widget, además de tener eventos que son comúnes a muchos widgets, tienen los suyos propios. Por ejemplo, el evento Toggled existe solamente para los botones de la clase ToggleButton ( este evento es el que sucede cuando se tiene un botón tipo radio o casilla, y se selecciona ).

Todo evento, al suceder, lanza una señal ( o signal ). Por ello es que es necesario "conectar" una método para que "atrape" a esa señal ( y en dado caso, responda a ella ). Estos métodos son llamados Callback Method, y son muy importantes en el desarrollo de aplicaciones GUI ( gráficas ).

Tales eventos existen en C# mediante delegados; la clase debe definir un delegado que ayude a "asociar" el evento con los Callback Methods, tal que cuando el evento sucede, estos métodos sean invocados a través de ese delegado ( que en realidad se define como un tipo event ). Los Callback Methods, para ser pasados al evento, deben de tener un tipo de regreso void, además de tomar dos argumentos: uno de tipo object, que es propiamente el widget en cuestión, y un tipo que almacene los argumentos, comúnmente de tipo EventArgs o similar. Así, un Callback podría ser:

 
        void CallbackMethod ( object obj, EventArgs args ) {
                ...
        }

Siendo un poco más concretos, veremos que la clase Window, por ejemplo, posee el evento DeleteEvent, que sucede cuando la ventana es cerrada. Así que si tuvieramos un objeto del tipo Window, para "conectar" el evento en cuestión, tendríamos que agregarle el método que será llamado cuando ese evento se produzca: WindowObject.DeleteEvent += new EventHandler (CallbackMethod).

Pero basta de tanta teoría, pasemos a ver un ejemplo que nos esclarezca un poco el panorama acerca de eventos y señales:

 
using System; 
using Gtk; 
using GtkSharp; 

 public class Tester {

        // Definimos nuestro Callback Method
        static void DetenerAplicacion ( object obj, DeleteEventArgs args )
        {

                Application.Quit();

        }
 
        public static void Main ( string[] args ) {
 
                // Esta linea es indispensable en todas nuestras aplicaciones
                Application.Init();

                Window win = new Window(" Hola Mundo! ");
                Label lab = new Label(" ¡ Hola Mundo ! ");

                win.BorderWidth = 10; // Especificamos el ancho del borde
                win.SetDefaultSize(200, 200); // Especificamos el tamaño

                win.DeleteEvent += new DeleteEventHandler(DetenerAplicacion);

                win.Add(lab);
 
                lab.Show();
                win.Show();

                Application.Run();
 
        } 
 
 } 

Sí, así es ... ¡ con esto, ya no necesitamos matar al proceso !, finalmente pudimos cerrar la ventana como debe ser. Primero que nada, observemos el método DetenerAplicacion ( object obj, DeleteEventArgs args ), que cumple con el delegado especificado para ese método en la clase Window; nótese también que, a diferencia de muchos eventos que reciben EventArgs, el evento DeleteEvent recibe argumentos mediante la clase DeleteEventArgs.

Pasando al contenido de nuestra "callback", veremos la línea Application.Quit(), que se encarga de detener la aplicación por completo. Además hay que notar que no hicimos uso de los argumentos ( loc cuáles son pasados a través del evento ).

Finalmente, observemos win.DeleteEvent += new DeleteEventHandler(DetenerAplicacion), que se encarga de agregar un delegado del tipo DeleteEventHandler al evento DeleteEvent, teniendo como parámetro el simple nombre de nuestro método DetenerAplicacion ().