Este post es continuación de este anterior sobre Delegates. Si ya conocés el tema no te va a hacer falta empezar por él.
En .NET tenemos la posibilidad de publicar un evento, al cual uno o más objetos pueden suscribirse.
Cuando se produce el evento, el aplicativo informa a los objetos suscriptos, que en el entorno del evento ejecutarán el código que contengan en la definición de su clase.
Al producirse el evento se invoca un método definido por medio de un delegado
Este Delegate debe recibir dos parámetros de entrada, el primero de tipo Object que recibe el objeto que produce el evento, el segundo es algún objeto que derive de la clase EventArgs.
Vamos a ver un ejemplo con el que jamás podremos a llamar la atención de nadie que nos interese. 🙂
Desde este link pueden descargarlo.
Vamos a tener tres formularios, el primero de ellos tiene un TrackBar que cuando se modifica los otros dos formularios se «enteran» y muestran la modificación a través de un textBox.
El primer punto interesante es que no tengo que agregar nada de código en los formularios que se «enteran» del evento. En el ejemplo que les dejo, en VB.NET y C#, podemos ver que en los Form2 y Form3 sólo hay estructura para verse como formularios y para soportar un textBox.
Empiezo por la clase TrackBarChangeEventsArgs que encapsula el valor que toma el TrackBar cuando se modifica su estado.
[VB]
Imports System
»’ <summary>
»’ Encapsula el argumento del evento, en este caso es un entero
»’ que representa al valor del TrackBar.
»’ </summary>
»’ <remarks>La clase hereda de EventArgs.</remarks>
Class TrackBarChangeEventsArgs
Inherits EventArgs
Private mChange As Integer
»’ <summary>
»’ Constructor
»’ </summary>
»’ <param name=»pChange»>Valor del TrackBar.</param>
»’ <remarks></remarks>
Public Sub New(ByVal pChange As Integer)
MyBase.New()
Me.mChange = pChange
End Sub
»’ <summary>
»’ Publica el valor del argumento del evento, en este caso
»’ el valor del TrackBar.
»’ </summary>
»’ <value></value>
»’ <returns>Valor del TrackBar</returns>
»’ <remarks></remarks>
Public ReadOnly Property Change() As Integer
Get
Return mChange
End Get
End Property
End Class
[C#]
using System;
/// <summary>
/// Encapsula el argumento del evento, en este caso es un entero
/// que representa al valor del TrackBar.
/// </summary>
/// <remarks>La clase hereda de EventArgs.</remarks>
class TrackBarChangeEventsArgs : EventArgs
{
private int mChange;
/// <summary>
/// Constructor
/// </summary>
/// <param name=»pChange»>Valor del TrackBar.</param>
/// <remarks></remarks>
public TrackBarChangeEventsArgs(int pChange)
{
this.mChange = pChange;
}
/// <summary>
/// Publica el valor del argumento del evento, en este caso
/// el valor del TrackBar.
/// </summary>
/// <value></value>
/// <returns>Valor del TrackBar</returns>
/// <remarks></remarks>
public int Change
{
get
{
return mChange;
}
}
}
Podemos ver que la clase deriva de EventArgs, tiene un constructor que recibe como parámetro el valor del TrackBar y publica al mismo mediante una propiedad Read Only.
Ahora veamos la clase encargada de publicar el evento, en el ejemplo es TrackBarAdministrador, en ella es donde se declara el Delegate de nombre TrackBarChangeEventHandler, que, como mencioné antes, recibe dos parámetros uno de tipo Object que contiene al objeto que disparó el evento y otro que deriva de EventArgs, esta ves es TrackBarChangeEventArgs.
A continuación se declara el evento OnTrackBarChangeHandler del tipo Delegate TrackBarChangeEventHandler.
La clase tiene un único método llamado ChangeTrackBar que acepta un sólo parámetro de tipo entero que es el valor del TrackBar. En este método se declara una variable llamada e del tipo de la clase TrackBarChangeEventsArgs (la que encapsula y publica el valor del TrackBar) y se le pasa el parámetro que se recibió, el entero que representa el valor del TrackBar. Ahora se dispara el evento OnTrackBarChangeHandler pasándole como parámetros el propio objeto (que es una instancia de la clase TrackBarAdministrador) y con esto queda publicado el evento.
Veamos la clase:
[VB]
Imports System
»’ <summary>
»’ Administra el evento de cambio de valor del TrackBar.
»’ </summary>
»’ <remarks></remarks>
Class TrackBarAdministrador
»’ <summary>
»’ Declaro un Delegate de nombre TrackBarChangeEventHandler. A
»’ Continuación declaro un evento del tipo del Delegate, que
»’ será el evento a propagar.
»’ </summary>
»’ <param name=»source»>Parámetro de entrada de tipo Object</param>
»’ <param name=»e»>Parámetro de entrada de tipo TrackBarChangeEventsArgs</param>
»’ <remarks>Esta es la clase que administra el evento a producirse al
»’ cambiar el valor del TrackBar</remarks>
Public Delegate Sub TrackBarChangeEventHandler(ByVal source As Object, ByVal e As TrackBarChangeEventsArgs)
Public Event OnTrackBarChangeHandler As TrackBarChangeEventHandler
»’ <summary>
»’ Método que recibe el valor a propagar.
»’ </summary>
»’ <param name=»pChange»>Valor del TrackBar a propagar.</param>
»’ <remarks></remarks>
Public Sub ChangeTrackBar(ByVal pChange As Integer)
Dim e As TrackBarChangeEventsArgs = New TrackBarChangeEventsArgs(pChange)
RaiseEvent OnTrackBarChangeHandler(Me, e)
End Sub
End Class
[C#]
using System;
/// <summary>
/// Administra el evento de cambio de valor del TrackBar.
/// </summary>
/// <remarks></remarks>
class TrackBarAdministrador
{
public event TrackBarChangeEventHandler OnTrackBarChangeHandler;
/// <summary>
/// Método que recibe el valor a propagar.
/// </summary>
/// <param name=»pChange»>Valor del TrackBar a propagar.</param>
/// <remarks></remarks>
public void ChangeTrackBar(int pChange)
{
TrackBarChangeEventsArgs e = new TrackBarChangeEventsArgs(pChange);
OnTrackBarChangeHandler(this, e);
}
/// <summary>
/// Declaro un Delegate de nombre TrackBarChangeEventHandler. A
/// Continuación declaro un evento del tipo del Delegate, que
/// será el evento a propagar.
/// </summary>
/// <param name=»source»>Parámetro de entrada de tipo Object</param>
/// <param name=»e»>Parámetro de entrada de tipo TrackBarChangeEventsArgs</param>
/// <remarks>Esta es la clase que administra el evento a producirse al
/// cambiar el valor del TrackBar</remarks>
public delegate void TrackBarChangeEventHandler(object source, TrackBarChangeEventsArgs e);
}
Nos queda por ver la clase engargada de notificar la ocurrencia del evento que en este caso se llama TrackBarObservador.
Si bien la clase tiene este nombre, esto no significa que estemos aplicando el patrón Observer, para quien le interese este patrón acá hay un artículo descriptivo.
Esta clase tiene un constructor que acepta como parámetro un objeto del tipo de la clase TrackBarAdministrador, lo guarda en una variable local y vincula al evento OnTrackBarChangeHandler declarado en la clase TrackBarAdministrador al método OnTrackBarChange definido más adelante en esta misma clase. Este método es donde se realizan las suscripciones de los formularios Form2 y Form3 que serán notificados del cambio en el TrackBar.
[VB]
Imports System
»’ <summary>
»’ Informa a los formularios sobre el evento que administra TrackBarAdministrador.
»’ </summary>
»’ <remarks></remarks>
Class TrackBarObservador
»’ <summary>
»’ Variable local del tipo de la clase que administra el evento
»’ a producirse al cambiar el vaor del TrackBar.
»’ </summary>
»’ <remarks></remarks>
Private mTrackBarAdministrador As TrackBarAdministrador
»’ <summary>
»’ Constructor
»’ </summary>
»’ <param name=»pTrackBarAdministrador»>Recibe una instancia de la clase
»’ que administra el evento a producirse al cambiar el valor del
»’ TrackBar</param>
»’ <remarks>Se agrega al método local OnTrackBarChange como manipulador
»’ del evento de tipo Delegate declarado en la clase TrackBarAdministrador.</remarks>
Public Sub New(ByVal pTrackBarAdministrador As TrackBarAdministrador)
‘MyBase.New()
Me.mTrackBarAdministrador = pTrackBarAdministrador
AddHandler mTrackBarAdministrador.OnTrackBarChangeHandler, AddressOf Me.OnTrackBarChange
End Sub
»’ <summary>
»’ Método que manipula al evento a producirse al variar el valor del TrackBar.
»’ </summary>
»’ <param name=»source»>Parámetro de entrada de tipo Object</param>
»’ <param name=»e»>Parámetro de entrada de tipo TrackBarChangeEventsArgs</param>
»’ <remarks>Es importante destacar que los parámetros de este método deben ser
»’ idénticos a los de la firma del evento de tipo Delegate declarado en la clase
»’ TrackBarAdministrador.</remarks>
Private Sub OnTrackBarChange(ByVal source As Object, ByVal e As TrackBarChangeEventsArgs)
Form2.txtValor.Text = e.Change
Form3.txtValor.Text = e.Change
End Sub
End Class
[C#]
using System;
/// <summary>
/// Informa a los formularios sobre el evento que administra TrackBarAdministrador.
/// </summary>
/// <remarks></remarks>
class TrackBarObservador
{
Form2 miForm2 = new Form2();
Form3 miForm3 = new Form3();
/// <summary>
/// Variable local del tipo de la clase que administra el evento
/// a producirse al cambiar el vaor del TrackBar.
/// </summary>
/// <remarks></remarks>
private TrackBarAdministrador mTrackBarAdministrador;
/// <summary>
/// Constructor
/// </summary>
/// <param name=»pTrackBarAdministrador»>Recibe una instancia de la clase
/// que administra el evento a producirse al cambiar el valor del
/// TrackBar</param>
/// <remarks>Se agrega al método local OnTrackBarChange como manipulador
/// del evento de tipo Delegate declarado en la clase TrackBarAdministrador.</remarks>
public TrackBarObservador(TrackBarAdministrador pTrackBarAdministrador)
{
this.miForm2.Show();
this.miForm3.Show();
this.mTrackBarAdministrador = pTrackBarAdministrador;
mTrackBarAdministrador.OnTrackBarChangeHandler += new TrackBarAdministrador.TrackBarChangeEventHandler(this.OnTrackBarChange);
}
/// <summary>
/// Método que manipula al evento a producirse al variar el valor del TrackBar.
/// </summary>
/// <param name=»source»>Parámetro de entrada de tipo Object</param>
/// <param name=»e»>Parámetro de entrada de tipo TrackBarChangeEventsArgs</param>
/// <remarks>Es importante destacar que los parámetros de este método deben ser
/// idénticos a los de la firma del evento de tipo Delegate declarado en la clase
/// TrackBarAdministrador.</remarks>
private void OnTrackBarChange(object source, TrackBarChangeEventsArgs e)
{
this.miForm2.txtValor.Text = e.Change.ToString();
this.miForm3.txtValor.Text = e.Change.ToString();
}
}
Pasamos ahora al Form1 que es el que controla la aplicación. Este formulario en su componente visual contiene un TrackBar. En él se declaran una variable local de tipo de la clase TrackBarAdministrador, otra más del tipo de la clase TrackBarObservador y se le pasa la variable de tipo TrackBarAdministrador, recién declarada, como parámetro.
En el evento Scroll del TrackBar, es el que se dispara al cambiar manualmente su valor, ejecutamos el método ChangeTrackBar declarado en la clase TrackBarAdministrador que es el encargado de disparar el evento OnTrackBarChangeHandler y se cierra el círculo.
[VB]
»’ <summary>
»’ Desde este formulario se controlan los valores de Título y
»’ TextBox de los otros dos.
»’ </summary>
»’ <remarks></remarks>
Public Class Form1
»’ <summary>
»’ Declaro una variable local del tipo TrackBarAdministrador. Luego otra del
»’ tipo TrackBarObservador, a la que se le pasa TrackBarAdministrador como
»’ parámetro de entrada.
»’ </summary>
»’ <remarks></remarks>
Private mTrackBarAdministrador As TrackBarAdministrador = New TrackBarAdministrador
Private mTrackBarObservador As TrackBarObservador = New TrackBarObservador(mTrackBarAdministrador)
»’ <summary>
»’ Muestro los formularios que se recibirán al evento desde la clase
»’ TrackBarObservador.
»’ </summary>
»’ <param name=»sender»></param>
»’ <param name=»e»></param>
»’ <remarks></remarks>
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Form2.Show()
Form3.Show()
End Sub
»’ <summary>
»’ Al modificarse el valor del TrackBar se dispara el evento ChangeTrackBar
»’ declarado en TrackBarAdministrador.
»’ </summary>
»’ <param name=»sender»></param>
»’ <param name=»e»></param>
»’ <remarks></remarks>
Private Sub TrackBar_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar.Scroll
mTrackBarAdministrador.ChangeTrackBar(sender.Value)
End Sub
End Class
[C#]
using System;
using System.Windows.Forms;
/// <summary>
/// Desde este formulario se controlan los valores de Título y
/// TextBox de los otros dos.
/// </summary>
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// Declaro una variable local del tipo TrackBarAdministrador. Luego otra del
/// tipo TrackBarObservador, a la que se le pasa TrackBarAdministrador como
/// parámetro de entrada.
/// </summary>
static TrackBarAdministrador mTrackBarAdministrador = new TrackBarAdministrador();
TrackBarObservador mTrackBarObservador = new TrackBarObservador(mTrackBarAdministrador);
/// <summary>
/// Muestro los formularios que se recibirán al evento desde la clase
/// TrackBarObservador.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
/// <remarks></remarks>
private void Form1_Load(object sender, System.EventArgs e)
{
Application.Run(new Form2());
Application.Run(new Form3());
}
/// <summary>
/// Al modificarse el valor del TrackBar se dispara el evento ChangeTrackBar
/// declarado en TrackBarAdministrador.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
/// <remarks></remarks>
private void trackBar_Scroll(object sender, System.EventArgs e)
{
mTrackBarAdministrador.ChangeTrackBar(((System.Windows.Forms.TrackBar)(sender)).Value);
}
}
No publico el código de los otros dos formularios porque no contienen más código que el necesario para ser formularios y contener un textBox de nombre txtValor, pueden verificarlo en los ejemplos que les dejo acá para bajar y probar.
Con la idea de haber sido útil, me despido hasta la próxima. 🙂
6 comentarios
Comments feed for this article
miércoles 07 \07-03:00 May \07-03:00 2008 a 1:05:05
Oberdata - Delegados en C#
[…] Eventos y Delegados en VB y C# […]
jueves 06 \06-03:00 May \06-03:00 2010 a 17:05:51
agustin
Hola, se que este tema tiene cómo 2 años, pero hay alguna manera de descargar el código de ejemplo? El link está roto.
Gracias!
jueves 06 \06-03:00 May \06-03:00 2010 a 20:05:26
Carlos Marcelo Santos
Hola Agustín:
Gracias a tu aviso me entero que el host de mi sitio está roto. Ya hice el reclamo. Cuando me solucionen este inconveniente te aviso por este medio.
viernes 07 \07-03:00 May \07-03:00 2010 a 20:05:03
Carlos Marcelo Santos
Hola Agustín:
Ya me avisaron que mi sitio está reparado. Podés descargar el código cuando gustes.
domingo 21 \21-03:00 noviembre \21-03:00 2010 a 21:11:06
Osorio
como seria este codigo pero con botones en los formularios para vb.net
Gracias
martes 23 \23-03:00 noviembre \23-03:00 2010 a 14:11:30
Carlos Marcelo Santos
Hola Osorio:
No entiendo para qué necesitás unos botones.
Saludos.