Exportar (0) Imprimir
Expandir todo
Este artículo se tradujo de forma manual. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original
Personas que lo han encontrado útil: 1 de 1 - Valorar este tema

Provocar un evento

Si desea que su clase genere un evento, debe proporcionar los tres elementos siguientes:

  • Una clase que proporciona datos de eventos.

  • Un delegado de eventos.

  • La clase que genera el evento.

Por convención, en .NET Framework, cuando se genera un evento, pasa los datos de eventos a sus controladores de eventos. Los datos de eventos los proporciona la clase System.EventArgs o una clase que se deriva de ella.

A menudo, un evento no tiene datos personalizados; el hecho de que se desencadenara el evento proporciona toda la información que los controladores de eventos necesitan. En este caso, el evento puede pasar un objeto EventArgs a sus controladores. La clase EventArgs solo tiene un único miembro, Empty, que no se hereda de System.Object. Se puede usar para crear instancias de una nueva clase EventArgs.

Si un evento tiene datos personalizados, puede pasar a los controladores de eventos una instancia de una clase derivada de EventArgs. Dependiendo de los datos precisos que el evento pase a los controladores, quizás pueda usar una clase de datos de eventos existente en .NET Framework. Por ejemplo, si su controlador de eventos permite la acción asociada al evento que se va a cancelar, puede usar la clase CancelEventArgs.

Cuando necesite proporcionar datos personalizados a los controladores y no haya disponible una clase existente, puede definir su propia clase de datos de eventos. Se debe derivar de System.EventArgs. Por convención, esta clase se denomina EventNameEventArgs. En el ejemplo siguiente se muestra ese tipo de clase de datos de eventos personalizada. Define una clase denominada AlarmEventArgs que proporciona dos elementos de datos a los controladores de eventos: la propiedad Time de solo lectura, que indica cuándo se desencadenó la alarma, y la propiedad Snooze, que indica si la alarma se debe activar de nuevo después de un intervalo designado o si se deben cancelar las alarmas futuras.


public class AlarmEventArgs : EventArgs
{
   private DateTime alarmTime;
   private bool snoozeOn = true;

   public AlarmEventArgs(DateTime time)
   {
      this.alarmTime = time;
   }

   public DateTime Time
   {
      get { return this.alarmTime; }
   }

   public bool Snooze
   {
      get { return this.snoozeOn; }
      set { this.snoozeOn = value; }
   }   
}


Un delegado de eventos se usa para definir la firma del evento. Un delegado de eventos determinado corresponde normalmente a una clase de datos de eventos concreta. Por convención, los eventos de .NET Framework tienen la firma EventName(sender, e), donde sender es un Object que proporciona una referencia a la clase o estructura que desencadenó el evento, y e es un objeto EventArgs o un objeto derivado de EventArgs que proporciona datos de eventos. La definición de delegado suele tomar el formato EventNameHandler(sender, e).

Si está usando una clase de datos de eventos que ya está definida en la biblioteca de clases de .NET Framework o en una biblioteca de otro fabricante, es probable que en esa biblioteca también esté definido un delegado de eventos correspondiente. Por ejemplo, el delegado de EventHandler se puede usar junto con la clase EventArgs. Del mismo modo, el delegado de CancelEventHandler se puede usar junto con la clase CancelEventArgs.

Si define una clase de datos de eventos personalizada, también puede definir un delegado personalizado para definir la firma del evento o puede usar el delegado Action<T1, T2> genérico.

En el ejemplo siguiente se define un delegado de eventos denominado AlarmEventHandler.


public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);


La clase que genera el evento debe proporcionar la declaración de evento y definir un método que genera el evento. Además, debe proporcionar cierta lógica para generar el evento en una propiedad o en un método de clase.

Para definir un miembro de evento en su clase se emplea la palabra clave event en C# o la instrucción Event en Visual Basic. Cuando el compilador encuentra una declaración de evento en la clase, crea un miembro privado como:

private EventNameHandler eh = null;

El compilador también crea los dos métodos públicos add_EventName y remove_EventName. Estos métodos son enlaces de eventos que permiten combinar o quitar delegados del delegado de evento eh. El programador oculta los detalles.

NotaNota

En lenguajes que no sean C# y Visual Basic 2005, puede que el compilador no genere automáticamente el código correspondiente a un miembro de evento, y que se tengan que definir explícitamente los enlaces de eventos y el campo del delegado privado.

En el ejemplo siguiente se declara un evento denominado AlarmEvent. Se ha extraído del ejemplo para una clase denominada Alarm cuyo código fuente completo se muestra debajo. Observe que tiene la firma del delegado AlarmEventHandler.


public event AlarmEventHandler AlarmEvent;


Cuando haya definido su implementación de evento, deberá determinar cuándo provocar el evento. Para generar el evento se llama al método protegido OnEventName en la clase que definía el evento o en una clase derivada. A continuación, el método OnEventName genera el evento.

NotaNota

El método protegido OnEventName también permite que las clases derivadas reemplacen el evento sin adjuntarle un delegado. Una clase derivada siempre debe llamar al método OnEventName de la clase base para asegurarse de que los delegados registrados reciben el evento.

En el ejemplo siguiente se define el método OnAlarmEvent, que es responsable de generar el evento AlarmEvent.


protected void OnAlarmEvent(AlarmEventArgs e)
{
   AlarmEvent(this, e);
}  


En el ejemplo siguiente se define un método denominado Set que contiene la lógica para desencadenar el evento llamando al método OnAlarmEvent. Si las horas y los minutos de la hora de la alarma son iguales que las horas y los minutos de la hora actual, el método Set crea una instancia de un objeto AlarmEventArgs y le proporciona la hora a la que sonó la alarma. Una vez que se ejecutan los controladores de eventos, comprueba el valor de la propiedad Snooze. Si Snooze es false, no se va a generar ningún evento de alarma más, por lo que el método Set puede finalizar. Si Snooze es true, el valor de la propiedad Interval incrementa la hora a la que va a sonar la alarma.


public void Set()
{
   while (true) {
      System.Threading.Thread.Sleep(2000);
      DateTime currentTime = DateTime.Now;
      // Test whether it is time for the alarm to go off.
      if (currentTime.Hour == alarmTime.Hour && 
          currentTime.Minute == alarmTime.Minute)
      {    
         AlarmEventArgs args = new AlarmEventArgs(currentTime);
         OnAlarmEvent(args);
         if (! args.Snooze) 
            return;
         else
            this.alarmTime = this.alarmTime.AddMinutes(this.interval);
      }
   }
} 


En el ejemplo siguiente se incluye todo el código fuente para la clase Alarm.


public class Alarm
{
   private DateTime alarmTime;
   private int interval = 10;

   public event AlarmEventHandler AlarmEvent;

   public Alarm(DateTime time) : this(time, 10)
   {
   }

   public Alarm(DateTime time, int interval)
   {
      this.alarmTime = time;
      this.interval = interval;
   }

   public void Set()
   {
      while (true) {
         System.Threading.Thread.Sleep(2000);
         DateTime currentTime = DateTime.Now;
         // Test whether it is time for the alarm to go off.
         if (currentTime.Hour == alarmTime.Hour && 
             currentTime.Minute == alarmTime.Minute)
         {    
            AlarmEventArgs args = new AlarmEventArgs(currentTime);
            OnAlarmEvent(args);
            if (! args.Snooze) 
               return;
            else
               this.alarmTime = this.alarmTime.AddMinutes(this.interval);
         }
      }
   } 

   protected void OnAlarmEvent(AlarmEventArgs e)
   {
      AlarmEvent(this, e);
   }  
}


¿Te ha resultado útil?
(Caracteres restantes: 1500)
Gracias por sus comentarios

Adiciones de comunidad

Mostrar:
© 2014 Microsoft. Reservados todos los derechos.