2010-04-01 25 views
24

Me gustaría crear un método que tome un evento como argumento y le agregue eventHandler para manejarlo correctamente. De esta manera:¿Cómo pasar un evento a un método?

tengo dos eventos:

public event EventHandler Click; 
public event EventHandler Click2; 

Ahora me gustaría transmitir un evento en particular a mi método como este (pseudocódigo):

public AttachToHandleEvent(EventHandler MyEvent) 
{ 
    MyEvent += Item_Click; 
} 

private void Item_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show("lalala"); 
} 

ToolStripMenuItem tool = new ToolStripMenuItem(); 
AttachToHandleEvent(tool.Click); 

es posible?

Me di cuenta de que este código funcionaba bien, y volví a mi proyecto y noté que cuando paso un evento declarado en mi clase, funciona, pero cuando paso el evento de otra clase todavía no funciona.

Lo que consigue es este error:

The event 'System.Windows.Forms.ToolStripItem.Click' can only appear on the left hand side of += or -=

+0

@OJ sí, usted es tan inteligente! –

+0

@Petar Minchev No sé por qué ... Fuiste el primero y me ayudaste. Gracias. –

+0

He actualizado una pregunta para reflejar el problema que estoy tratando con el acero –

Respuesta

23

Mi respuesta original era adecuada dentro de la clase que definió el evento, pero desde entonces has actualizado tu pregunta para reflejar que deseas lograr esto desde fuera de la clase de definición, así que lo he rechazado.

Solo la clase que define un evento puede hacer referencia a la variable de delegado implícita que utiliza el evento. Desde fuera de esa clase, solo tiene acceso a los métodos add y remove, a través de += y -=. Esto significa que no puedes hacer lo que estás preguntando directamente. Sin embargo, puede usar un enfoque funcional.

class A{ 
    public event EventHandler Event1; 

    public void TriggerEvent1(){ 
     if(Event1 != null) 
      Event1(this, EventArgs.Empty); 
    } 
} 

class B{ 
    static void HandleEvent(object o, EventArgs e){ 
     Console.WriteLine("Woo-hoo!"); 
    } 

    static void AttachToEvent(Action<EventHandler> attach){ 
     attach(HandleEvent); 
    } 

    static void Main(){ 
     A a = new A(); 
     AttachToEvent(handler=>a.Event1 += handler); 
     a.TriggerEvent1(); 
    } 
} 
+0

lo he revisado para ver la versión actualizada de mi problema y, por desgracia, no funciona, ¿me pueden ayudar? –

+0

Intenté este enfoque y está funcionando. – hakan

2

Sólo tiene que escribir tool.Click += Item_Click;

Editar: "Los eventos sólo se pueden invocar desde dentro de la clase o estructura en la que (ella) se declaran" A partir de MSDN. Entonces, lo que estás tratando de hacer no es posible. ¿Podría elaborar más sobre sus necesidades? ¿Por qué querrías pasar un evento como parámetro?

+0

Oh ... así que mi código es malo en otro lado. ¡Gracias! –

+1

No es negativo para mí. Tu respuesta fue la primera y la correcta. He intentado una versión más larga de este código y no quería funcionar. He escrito esta pregunta aquí para pedir ayuda, pero cuando después de su respuesta he vuelto a verificar este sencillo ejemplo de aquí, ha resultado ser correcto a medida que escribía. Gracias . –

+1

Todavía tengo un problema. Perdón por pregunta extraviada, no es pricee y se centra en la situación cuando tengo un error –

3

No es posible. Puede usar un delegado en lugar de un evento si cumple con sus necesidades.

1
delegate void doIt(object sender, object data); 
    event doIt OnDoIt; 

    void add(doIt theDel) 
    { 
     OnDoIt += theDel; 
    } 

    void doIt1(object a, object b) 
    { 
    } 

    void doIt2(object a, object b) 
    { 
    } 

    void add() 
    { 
     add(doIt1); 
     add(doIt2); 
    } 
5

lo hice así:

public AttachToHandleEvent(Object obj, string EventName) 
{ 
    EventInfo mfi = obj.GetType().GetEvent(EventName); 
    MethodInfo mobj = mfi.GetAddMethod(); 
    mobj.Invoke(obj, new object[] { Item_Click}); 
} 

private void Item_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show("lalala"); 
} 

ToolStripMenuItem tool = new ToolStripMenuItem(); 
AttachToHandleEvent(tool "Click"); 

Gracias a todos por el consejo. Esta solución no podría hacerse sin su ayuda.

+0

Este código tiene algunos problemas con él. Hay una solución aquí: http://msdn.microsoft.com/en-us/library/ms228976%28v=vs.95%29.aspx#Y899 – cbp

-1

Su pregunta sugiere que tiene algunos mecanismos incorrectos: ¡No puede pasar eventos!

Lo más probable es que desee pasar una función como parámetro, por lo que el método de llamada llamará a ese otro método en algún momento. En términos técnicos, este es un delegado. Sugiero usar la clase de acción ya definida. He aquí un fragmento de ejemplo:

void MyFunction (string otherArguments, Action onFinished){ 
    ... 
    if (onFinished != null) 
     onFinished.Invoke(); 
} 

Lo bueno de esto es que cuando se llama a MyFunction puede declarar la acción utilizando la sintaxis de línea:

MyFunction("my other argument",()=>{ 
    ///do stuff here, which will be execuded when the action is invoked 
}); 
Cuestiones relacionadas