Pregunta

¿Es posible bajo cualquier conjunto de circunstancias poder lograr esto?

Mis circunstancias actuales son estas:

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 primer pensamiento fue 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 un error terriblemente feo, pero debería funcionar...¿Debe haber una solución más elegante?La biblioteca .NET hace esto todo el tiempo con controladores de mensajes y eventos de llamada en Control.¿Alguien más tiene otras ideas o mejores?

¿Fue útil?

Solución

Sólo necesitas agregar un método público para invocar el evento.Microsoft ya hace esto para algunos eventos como Realizar clic para controles que exponen un Hacer clic evento.

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

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

Luego haría lo siguiente dentro de su controlador de eventos de ejemplo...

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

Otros consejos

La palabra clave event en c# modifica la declaración del delegado.Evita la asignación directa al delegado (solo puedes usar += y -= en un evento) y evita la invocación del delegado desde fuera de la clase.

Entonces podrías modificar tu código para que se vea así:

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

Luego puedes invocar el evento desde fuera de la clase de esta manera.

myCustomGUIElement.Click(sender,args);

El inconveniente es que el código que utiliza la clase puede sobrescribir cualquier controlador registrado muy fácilmente con código como este:

myCustomGUIElement.Click = null;

lo cual no está permitido si el delegado Click se declara como un evento.

Realmente deberías envolver el código que deseas poder ejecutar desde el exterior en un método.Ese método puede entonces hacer lo que haría su evento, y ese evento también llamaría a ese método.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top