Delegados, Eventos y Métodos anónimos
Introducción: Implementando una interfaz gráfica con windows forms, teniendo un MDI principal y un par de formularios hijos, vi la necesidad que en un momento dado, un formulario hijo realice algo que el padre tiene que interceptar, y tomar cartas en el asunto. En este caso necesitaba setear la propiedad Text del MDI, a partir de alguna acción de un formulario hijo; algo sencillo.
En C# y sin la posibilidad de usar algo análogo al namespace My, que posee la gente de VB.Net, tuve que recurrir a un Eventos y Delegados,...y ya que estamos...Métodos anónimos.
En VB.Net, estando en formulario hijo con el namespace my seria algo bastante tonto:My.Forms.MDIMain.Text = nombredeltitulo
En C# me las arregle con un mecanismo que permita que el padre (MDI principal) se quede a la "escucha" de un evento, y así iniciar acciones, pero con información que le provee el hijo. Es decir:
- Los metodos a ejecutar: son del MDI principal
- Y la información necesaria -los parametros- : provienen del form hijo.
Ahora bien, como se podrían implementar estos tres conceptos juntos para resolver esto ?
Ahora pasemos a un ejemplo donde se vé una interacción entre los objetos:
using System;Primeramente declararemos un delegado: EventHandler, que podrá apuntar a metodos que contengan como argumentos el tipo string y que no retornen valores (void).
// Declaracion del delegado
public delegate void EventHandler(string str);
public class Program
{
public static void Main()
{
TestHandler tb = new TestHandler();
//Tres maneras de hacer lo mismo
//1- asignacion comun
tb.Evento += new EventHandler(MetodoStringToUpper);
//2- asignacion por inferencia de tipos
tb.Evento += MetodoStringToLower;
//3- asignacion con metodo anonimo
tb.Evento += delegate(string str)
{
string otrostring =
String.Format("Metodo Anonimo: {0}",str);
Console.WriteLine(otrostring);
};
tb.Disparar();
Console.ReadLine();
}
public static void MetodoStringToUpper(string str)
{
Console.WriteLine(str.ToUpper());
}
public static void MetodoStringToLower(string str)
{
Console.WriteLine(str.ToLower());
}
}
class TestHandler
{
//Evento de tipo EventHandler
public event EventHandler Evento;
public void Disparar()
{
string mystring = "Dario.Net";
//Disparo el evento, con un string de parámetro
Evento(mystring);
}
}
Luego en la clase TestHandler se declara un evento: Evento, del tipo EventHandler (nuestro delegado).
Y la funcion: Disparar(); se encargará de disparar el evento con un string como argumento: mystring="Dario.Net".Vayamos al Main().
Instanciamos un objeto del tipo TestHandler, con el operador += y vamos agregando al evento, todos los métodos que queremos que se ejecuten, uno tras otro.Luego invocamos a Disparar(). y se invocan, en este orden los tres métodos: MetodoStringToUpper,MetodoStringToLower y el querido metodo anónimo.
Cosas a notar:El que dispara el evento es el TestHandler, y le pasa un parámetro: mystring.
Los métodos están en el Main, pero esos métodos se ejecutarán por el hijo...cosa loca no ?El método anonimo: es como si fuera un metodo más, pero definido en el momento de su uso, e inline (buenísimo!)
Bien, ahora que vimos el ejemplo (y espero que lo hayan entendido), imaginemos algo: hagamos de cuenta que Program es el Main, y TestHandler es el Form1. Y podemos solucionar facilmente el problema que plantee al comienzo...y muchos más!
Para profundizar les recomiendo este artículo.
Saludos y dejen comentarios.
Muy raro lo tuyo. Se supone que los forms cuando los haces MDI tenes que ponerle la propiedad MdiParent = form hijo. Tomano ventaja de eso yo de cabeza me mando a MdiParent.Text = "cualkiera";
en el peor de los casos haces cast de MdiParent al tipo que es, si es que le agregaste metodos y queres llamarlos. Me perdi de algo? :$