2010-02-22 11 views
5

Estoy escribiendo una Biblioteca de clases que será utilizada por otras aplicaciones. Lo estoy escribiendo en C# .NET. Tengo un problema con desencadenar eventos en todas las clases. Esto es lo que tengo que hacer ...¿Cómo se desencadena un evento en todas las clases?

public class ClassLibrary 
{ 
    public event EventHandler DeviceAttached; 

    public ClassLibrary() 
    { 
     // do some stuff 
     OtherClass.Start(); 
    } 
} 

public class OtherClass : Form 
{ 
    public Start() 
    { 
     // do things here to initialize receiving messages 
    } 

    protected override void WndProc (ref message m) 
    { 
     if (....) 
     { 
      // THIS IS WHERE I WANT TO TRIGGER THE DEVICE ATTACHED EVENT IN ClassLibrary 
      // I can't seem to access the eventhandler here to trigger it. 
      // How do I do it? 

     } 
     base.WndProc(ref m); 
    } 

} 

Luego, en la aplicación que está utilizando la biblioteca de clases voy a hacer esto ...

public class ClientApplication 
{ 
    void main() 
    { 
     ClassLibrary myCL = new ClassLibrary(); 
     myCL.DeviceAttached += new EventHandler(myCl_deviceAttached); 
    } 

    void myCl_deviceAttached(object sender, EventArgs e) 
    { 
     //do stuff... 
    } 
} 

Respuesta

1

Creo que debería cambiar su perspectiva sobre cómo funcionan los eventos. OtherClass debe "poseer" el evento y desencadenarlo. ClassLibrary o ClientApplication (cualquiera que elija) "escucha" el evento "suscribiéndose" a él y realiza una determinada acción cuando ocurre este evento.

cómo implementar esto:

public class ClassLibrary 
{ 
    public OtherClass myOtherCl; 

    public ClassLibrary() 
    { 
     myOtherCl= new OtherClass(); 
     myOtherCl.Start(); 
    } 
} 

activar el evento en la clase donde lógicamente sucede, en el que se detecta.

public class OtherClass : Form 
{ 
    public event EventHandler DeviceAttached; 

    public Start() 
    { 
     // do things here to initialize receiving messages 
    } 

    protected override void WndProc (ref message m) 
    { 
     if (....) 
     { 
      OnDeviceAttach(); 
     } 
     base.WndProc(ref m); 
    } 

     public void OnDeviceAttach() 
     { 
      if (DeviceAttached != null) 
       DeviceAttached(); 
     } 

} 

Por último, el que tiene que escuchar al evento necesita acceder a la instancia de la clase la realización del evento, es por eso myOtherCl se hizo pública en este ejemplo.

public class ClientApplication 
{ 
    void main() 
    { 
     ClassLibrary myCL = new ClassLibrary(); 
     myCL.myOtherCl.DeviceAttached += new EventHandler(myCl_deviceAttached); 
    } 

    void myCl_deviceAttached(object sender, EventArgs e) 
    { 
     //do stuff... 
    } 
} 
+0

Como complemento, asegúrese de copiar el controlador de eventos antes de activarlo para seguridad de subprocesos: 'var ev = DeviceAtached; if (ev! = null) ev(); ' – Tanzelax

8

No se puede hacer esto. Los eventos solo pueden surgir desde dentro de la clase que declara el evento.

Normalmente, se añadiría un método en su clase para provocar el evento, y llamar al método:

public class ClassLibrary 
{ 
    public event EventHandler DeviceAttached; 
    public void NotifyDeviceAttached() 
    { 
     // Do processing and raise event 
    } 

Luego, en el otro código, que le acaba de llamar myCL.NotifyDeviceAttached();

+0

¿NotifyDeviceAttached debe ser estático? De lo contrario, ¿cómo hago referencia a la instancia de ClassLibrary de OtherClass cuando OtherClass no la creó? – PICyourBrain

+0

Tendrá que proporcionar su formulario con una instancia adecuada. De lo contrario, puede hacer que NotifyDeviceAttached sea estático, pero también tendrá que hacer de su controlador de eventos un evento estático también ... Todo es cuestión de diseño. –

1

Evento los manejadores solo pueden ser llamados directamente por la clase que los declaró. Si necesita llamar a ClassLibrary.DeviceAttached desde fuera esa clase, es necesario agregar un método de utilidad como la siguiente:

public void OnDeviceAttached() 
{ 
    DeviceAttached(); 
} 
+0

hmmm ok. ¿Se puede pasar el evento a la clase como referencia y llamarlo de esa manera? – PICyourBrain

+0

@Jordan S: No. Los diseñadores de C# lo hicieron deliberadamente para que no pueda generar un evento de otra clase, incluso una subclase. DEBES hacerlo desde la clase que declaró el evento. –

+0

¿OnDeviceAttached debe ser estático? De lo contrario, ¿cómo hago referencia a la instancia de ClassLibrary de OtherClass cuando OtherClass no la creó? – PICyourBrain

1

Es posible que no desee utilizar un evento en todos aquí. Esto es una simplificación excesiva, pero generalmente un evento es algo que plantea un componente secundario cuando necesita comunicar algo a su padre. En su caso (estoy deduciendo de su código), su formulario está escuchando un mensaje específico (¿cuando un dispositivo está conectado?), Y cuando detecta ese mensaje, debe decirlo al myCL. Para este propósito, en su lugar, simplemente cree un método en ClassLibrary y llámelo desde su formulario.

+0

Mi ejemplo omite muchos detalles. OtherClass no es en realidad una forma visible, simplemente hereda de Form para que pueda usarse para captar los mensajes de Windows cuando se conectan/reciben dispositivos USB ... Sé que es confuso. – PICyourBrain

Cuestiones relacionadas