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;// 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 parametro Evento(mystring); } }
Primeramente declararemos un delegado: EventHandler, que podrá apuntar a metodos que contengan como argumentos el tipo string y que no retornen valores (void).
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.
3 Responses to Delegados, Eventos y Métodos anónimos
Leave a Reply Cancel reply
-
Categories
- .NET
- ActiveRecord
- agil
- Alt.Net
- AOP
- Asp.net MVC
- blog
- C#
- codegeneration
- cosas interesantes
- db4o
- db4o-analyzer
- DLR
- enterprise-library
- expresiones regulares
- General
- Hibernate
- IoC
- it
- Java
- LINQ
- Linux
- Lucene
- Mocking
- Mono
- monosms
- MVC
- NAnt
- NHibernate
- NHibernate.Burrow
- NHibernate.Contrib
- NHibernate.Validator
- noticias
- O/R Mapping
- Open Source
- patrones
- personal
- podcast
- programación
- Redes Neuronales
- Refactoring
- regex
- Scrum
- Security
- Shards
- Sin Categoría
- Spring
- SqlServer
- Testing
- tips
- Tool
- tutorial
- Ubuntu
- uNHAddIns
- video
- Virtualización
- Visual Basic.Net
- Visual Studio
- VMWare
- Web
-
Articles
- June 2011
- May 2011
- November 2009
- October 2009
- April 2009
- March 2009
- February 2009
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- March 2006
- February 2006
- December 2005
- November 2005
- October 2005
-
Meta





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? :$
Buen tip Guille. La verdad que con este approach queda solucionado facilmente el problema con los MDI y el .Text, y usando el casting se puede usar todo del Mdi que esté usando.
Pero para enfoques más complejos se queda corto. Podría usarse tambien para el caso de que varios formularios estén esperando por un evento, por ejemplo si se llama a algún formulario que realiza una busqueda, y el resultado afecta a varios forms que están activos.
Tiene más un gustivo a observer
Si hay algo que me gusta de .Net es la manera de implementar facilmente los patrones conocidos.
Para conocer sobre Observer:
Patron Observer
Claro, segun lo que tengo entendido delegates / events y las cosas esas (otra vez) no es invento de Microsoft. Delegates en .net es mas bien una implementacion de observer, yo no diría que observer es facil de implementar en .net sino facil de usar.
Este es solo uno de los ejemplos de distintos patrones que estan integrados en el .net. Tambien podes citar Composite Design pattern cuando creas un componente (clase Component)