2008-09-20 4 views
12

¿Es posible bajo cualquier circunstancia ser capaz de lograr esto?¿Llamar a eventos de C# desde fuera de la clase propietaria?

mis circunstancias actuales son esto:

public class CustomForm : Form 
{ 
    public class CustomGUIElement 
    { 
    ... 
     public event MouseEventHandler Click; 
     // etc, and so forth. 
    ... 
    } 

    private List<CustomGUIElement> _elements; 

    ... 

    public void CustomForm_Click(object sender, MouseEventArgs e) 
    { 
     // we might want to call one of the _elements[n].Click in here 
     // but we can't because we aren't in the same class. 
    } 
} 

Mi primera idea era tener una función similar a:

internal enum GUIElementHandlers { Click, ... } 
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) { 
    switch (h) { 
     case Click: 
      this.Click(this, (EventArgs)args[0]); 
      break; 
     ... // etc and so forth 
    } 
} 

Es una chapuza horriblemente feo, pero debería funcionar ... debe ser una solución más elegante sin embargo? La biblioteca .NET hace esto todo el tiempo con controladores de mensajes y eventos de llamada en Control. ¿Alguien más tiene alguna otra/mejor idea?

Respuesta

24

Solo tiene que agregar un método público para invocar el evento. Microsoft ya hace esto para algunos eventos como PerformClick para controles que exponen un evento Click.

public class CustomGUIElement  
{ 
    public void PerformClick() 
    { 
     OnClick(EventArgs.Empty); 
    } 

    protected virtual void OnClick(EventArgs e) 
    { 
     if (Click != null) 
      Click(this, e); 
    } 
} 

A continuación, haga lo siguiente dentro de su ejemplo controlador de eventos ...

public void CustomForm_Click(object sender, MouseEventArgs e)   
{ 
    _elements[0].PerformClick(); 
} 
+1

Creo que él planteó el evento desde fuera de la clase de eventos? –

+1

Llama a PerformClick() desde fuera de la clase de eventos. –

+0

No, este es el estilo de lo que estaba buscando hacer; es decir. llamando al evento desde fuera de la clase del evento. Solo esperaba que hubiera una forma de evitar el método. Supongo que iré con la solución interna que publiqué, este formulario personalizado estará en una DLL, por lo que las cosas internas estarán ocultas. –

1

Debería envolver el código que desea ejecutar desde el exterior en un método. Ese método puede hacer lo que haga su evento, y ese evento también llamará a ese método.

+0

Funcionaría. Pobremente, pero funcionaría. Almacenar una lista de devoluciones de llamadas es esencialmente lo que hace un evento de todos modos. ¿Por qué hacer el esfuerzo de volver a implementar lo que ya está allí? –

7

La palabra clave evento en C# modifica la declaración del delegado. Impide la asignación directa al delegado (solo puede usar + = y - = en un evento) e impide la invocación del delegado desde fuera de la clase.

Por lo que podría alterar su código para tener este aspecto:

public class CustomGUIElement 
{ 
... 
    public MouseEventHandler Click; 
    // etc, and so forth. 
... 
} 

A continuación, puede invocar el evento desde fuera de la clase de esta manera.

myCustomGUIElement.Click(sender,args); 

El inconveniente es que el código utilizando la clase puede sobrescribir los gestores registrados con mucha facilidad con el código como este:

myCustomGUIElement.Click = null; 

que no está permitido si el clic delegado se declara como un evento.

+0

No lo había pensado así. La otra respuesta es aún más práctica, pero gracias por la comprensión. –

+0

Esta respuesta es lo que quería aprender. Gracias @Lee – uzay95

Cuestiones relacionadas