visual tiempo studio que programar por net eventos evento event ejemplo ejecucion crear control codigo botones boton c# delegates

c# - tiempo - programar evento click en visual basic



¿Cómo puedo pasar un evento a una función en C#? (7)

Estoy buscando pasar un evento a una función de ayuda. Esta función adjuntará un método al evento. Sin embargo, estoy teniendo problemas para pasar el evento correctamente. He intentado pasar un EventHandler<TEventArgs> . Se compila, pero los eventos no se adjuntan (pero aún se agregan; parece que se hizo una copia del controlador de eventos).

Por ejemplo, si tengo esto:

public event EventHandler<EventArgs> MyEvent;

Y la función de ayuda:

public static void MyHelperFunction<TEventArgs>(EventHandler<TEventArgs> eventToAttachTo) { eventToAttachTo += (sender, e) => { Console.WriteLine("Hello world"); }; }

Y la persona que llama:

MyHelperFunction(MyEvent); MyEvent(null, new EventArgs()); // Does nothing.


Acabo de llegar con este pequeño ayudante. Si es tu Evento creado por ti mismo, puedes usar una envoltura como esta. Puede usar sus operadores + = para adjuntar manejadores de manera normal, pero puede pasar la envoltura e incluso elevar el evento desde otro lugar.

public class GenericEvent<T> where T:EventArgs { public event EventHandler<T> Source = delegate { }; public void Raise(object sender, T arg = default(T)) { Source(sender, arg); } public void Raise(T arg = default(T)) { Source(this, arg); } public void AddHandler(EventHandler<T> handler) { Source += handler; } public void RemoveHandler(EventHandler<T> handler) { Source -= handler; } public static GenericEvent<T> operator +(GenericEvent<T> genericEvent, EventHandler<T> handler) { genericEvent.AddHandler(handler); return genericEvent; } }

Crea el evento como:

public GenericEvent<EventArgs> MyEvent = new GenericEvent<EventArgs>();

Adjuntar manejadores:

MyEvent += (s,e) => {};

Elevar evento:

MyEvent.Raise();


Como muchos han señalado, pasar un evento a un método no es posible o no es simple.

  1. Por favor aclare, pero sospecho que su uso previsto se verá algo así como:

    void Register() { var super = new SuperHandler(); //not valid syntax: super.HandleEvent(MyEvent1); super.HandleEvent(MyEvent2); super.HandleEvent(MyEvent3); super.HandleEvent(MyEvent4); }

    Puede lograr esto simplemente haciendo accesibles públicamente sus controladores de eventos genéricos previstos (o internamente, si lo desea):

    public static class GenericHandler { public static void HandleAnyEvent(object sender, EventArgs e) { //handle } } public class SomeClass { void RegisterEvents() { var r = new EventRaiser(); r.ImportantThingHappened += GenericHandler.HandleAnyEvent; } }

    En este ejemplo, mi controlador catch-all está en una clase estática, pero también puede usar una clase no estática. Además, veo que en tu ejemplo has hecho el método genérico (TEventArgs). Debido a que todos los derivados de EventHandler (como CancelEventHandler) coinciden con el EventHandler base, no es necesario que impliquen genéricos (tampoco sería útil).

  2. Si la lógica de registro es compleja o si debe mantener el EventHandler en privado, considere usar los Eventos de interfaz . Es posible que esto no cumpla con su objetivo previsto de reducir la cantidad de código, pero le permitirá crear una clase que pueda manejar todos los eventos de un tipo específico de manera predecible.

    interface IRaiseEvents { event EventHandler ConnectionCreated; event EventHandler ConnectionLost; } public class SuperHandler { void RegisterEvents(IRaiseEvents raiser) { raiser.ConnectionCreated += (sender, args) => Console.WriteLine("Connected."); raiser.ConnectionLost += (sender, args) => Console.WriteLine("Disconnected."); } }


La razón por la que esto no funciona es + = cuando se aplica a un delegado crea un nuevo delegado que es la combinación de lo antiguo y lo nuevo. No modifica el delegado existente.

Para que esto funcione, deberá pasar el delegado por referencia.

public static void Helper(ref EventHandler<EventArgs> e) { e+= (x,y) => {}; }

La razón por la que esto funciona fuera del método es porque el LHS sigue siendo el campo real. Entonces + = creará un nuevo delegado y lo asignará de nuevo al campo miembro.


No es exactamente agradable, pero puedes usar la reflexión para hacer esto.

public EventMonitor(object eventObject, string eventName) { _eventObject = eventObject; _waitEvent = eventObject.GetType().GetEvent(eventName); _handler = new EventHandler(SetEvent); _waitEvent.AddEventHandler(eventObject, _handler); }

Donde eventObject es el objeto que contiene el evento y eventName es el nombre del evento. SetEvent es su controlador de eventos.

También tengo un método de eliminación como este:

public void Dispose() { _waitEvent.RemoveEventHandler(_eventObject, _handler); }


Pasa algo como Acción e = e => Evento + = e; ¿Y llamar desde el método con el manejador? Tiene la ventaja de trabajar con clases .NET.


Solo adivinando: ¿Has intentado pasarlo como ref?

public static void MyHelperFunction<TEventArgs>(ref EventHandler<TEventArgs> eventToAttachTo) MyHelperFunction(ref MyEvent);


Tengo una solución donde tengo dos interfaces. La primera interfaz tiene métodos para vincular ciertos eventos, mientras que la otra interfaz tiene métodos de eventos que pueden vincularse a esos eventos.

Los métodos de enlace de la primera interfaz toman la segunda interfaz como parámetro, lo que hace posible vincular los eventos a los métodos de eventos de cualquier clase que implemente la segunda interfaz.

¿Es eso comprensible, o preferiría algún código? :)