Markieren Sie das Kontrollkästchen Englisch, um die englische Version dieses Artikels anzuzeigen. Sie können den englischen Text auch in einem Popup-Fenster einblenden, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

Auslösen eines Ereignisses

Klassen, die ein Ereignis auslösen sollen, müssen diese drei Elemente bereitstellen:

  • Eine Klasse, die Ereignisdaten enthält.

  • Einen Ereignisdelegaten.

  • Die Klasse, die das Ereignis auslöst.

Üblicherweise werden Ereignisdaten beim Auslösen eines Ereignisses in .NET Framework an die Ereignishandler übergeben. Die Ereignisdaten werden von der System.EventArgs-Klasse oder einer davon abgeleiteten Klasse bereitgestellt.

Ereignisse weisen i. d. R. keine benutzerdefinierten Daten auf; das Auslösen des Ereignisses stellt alle erforderlichen Informationen für Ereignishandler bereit. In diesem Fall kann das Ereignis ein EventArgs-Objekt an die entsprechenden Handler übergeben. Die EventArgs-Klasse weist nur den Member Empty auf; dieser wird nicht von System.Object geerbt. Sie kann zum Instanziieren einer neuen EventArgs-Klasse verwendet werden.

Ereignisse, die benutzerdefinierte Daten aufweisen, können eine Instanz einer Klasse an Ereignishandler übergeben, die von EventArgs abgeleitet wurde. Je nachdem, welche Daten genau vom Ereignis an Handler übergeben werden, können Sie möglicherweise eine vorhandene Ereignisdatenklasse in .NET Framework verwenden. Wenn der Ereignishandler beispielsweise das Abbrechen der Aktion ermöglicht, die dem Ereignis zugeordnet ist, können Sie die CancelEventArgs-Klasse verwenden.

Wenn Sie benutzerdefinierte Daten für Handler bereitstellen müssen und keine vorhandene Klasse verfügbar ist, können Sie eine eigene Ereignisdatenklasse definieren. Diese muss von System.EventArgs abgeleitet werden. Der Name dieser Klasse lautet standardmäßig EventNameEventArgs. Im folgenden Beispiel wird eine entsprechende benutzerdefinierte Ereignisdatenklasse veranschaulicht. Im Beispiel wird die AlarmEventArgs-Klasse definiert, die zwei Datenelemente für Ereignishandler bereitstellt: die schreibgeschützte Time-Eigenschaft, die angibt, wann der Alarm ausgelöst wurde, und die Snooze-Eigenschaft, die angibt, ob der Alarm nach Ablauf eines festgelegten Zeitraums erneut ausgelöst werden soll.


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; }
   }   
}


Ereignisdelegaten werden verwendet, um die Signatur des Ereignisses zu definieren. Ein bestimmter Ereignisdelegat entspricht i. d. R. einer bestimmten Ereignisdatenklasse. Ereignisse in .NET Framework weisen üblicherweise die Signatur EventName(sender, e) auf. sender stellt dabei ein Object dar, das einen Verweis auf die Klasse oder Struktur enthält, die das Ereignis ausgelöst hat; e stellt ein EventArgs-Objekt oder ein Objekt dar, das von EventArgs abgeleitet wurde und Ereignisdaten bereitstellt. Die Delegatdefinition weist i. d. R. das Format EventNameHandler(sender, e) auf.

Wenn Sie eine Ereignisdatenklasse verwenden, die bereits in der .NET Framework-Klassenbibliothek oder in der Bibliothek eines Drittanbieters definiert ist, ist wahrscheinlich auch bereits ein entsprechender Ereignisdelegat in dieser Bibliothek definiert. Beispielsweise kann der EventHandler-Delegat zusammen mit der EventArgs-Klasse verwendet werden. Analog kann der CancelEventHandler-Delegat mit der CancelEventArgs-Klasse verwendet werden.

Wenn Sie eine benutzerdefinierte Ereignisdatenklasse definieren, können Sie auch einen benutzerdefinierten Delegaten definieren, um die Ereignissignatur anzugeben, oder Sie können den generischen Action<T1, T2>-Delegaten verwenden.

Im folgenden Beispiel wird der Ereignisdelegat AlarmEventHandler definiert.


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


Die Klasse, die das Ereignis auslöst, muss die Ereignisdeklaration bereitstellen und eine Methode angeben, die das Ereignis auslöst. Außerdem muss die Klasse Logik bereitstellen, um das Ereignis in einer Klasseneigenschaft oder einer Methode auszulösen.

Ereignismember in der Klasse werden mit dem event-Schlüsselwort in C# oder mit der Event-Anweisung in Visual Basic definiert. Wenn der Compiler eine Ereignisdeklaration in der Klasse vorfindet, erstellt er einen privaten Member wie den folgenden:

private EventNameHandler eh = null;

Der Compiler erstellt auch die öffentliche add_EventName-Methode und die öffentliche remove_EventName-Methode. Diese Methoden sind Ereignishooks, mit denen Delegaten kombiniert oder aus dem Ereignisdelegaten eh entfernt werden können. Die Details bleiben dem Programmierer verborgen.

HinweisHinweis

In anderen Sprachen als C# und Visual Basic 2005 generiert der Compiler möglicherweise den Code zu einem Ereignismember nicht automatisch. Ereignishooks und das private Delegatfeld müssen daher ggf. explizit definiert werden.

Im folgenden Beispiel wird das Ereignis AlarmEvent deklariert. Es wird für die Alarm-Klasse aus dem Beispiel exzerpiert; der vollständige Quellcode ist nachfolgend angegeben. Beachten Sie, dass es die Signatur des AlarmEventHandler-Delegaten aufweist.


public event AlarmEventHandler AlarmEvent;


Sobald Sie die Ereignisimplementierung definiert haben, müssen Sie festlegen, wann das Ereignis ausgelöst werden soll. Sie lösen das Ereignis aus, indem Sie die geschützte OnEventName-Methode in einer abgeleiteten Klasse oder in der Klasse aufrufen, die das Ereignis definiert. Das Ereignis wird dann von der OnEventName-Methode ausgelöst.

HinweisHinweis

Die geschützte OnEventName-Methode ermöglicht es abgeleiteten Klassen auch, das Ereignis ohne Anfügen eines Delegaten zu überschreiben. Eine abgeleitete Klasse muss immer die OnEventName-Methode der Basisklasse aufrufen, um sicherzustellen, dass registrierte Delegaten das Ereignis empfangen.

Im folgenden Beispiel wird die OnAlarmEvent-Methode definiert, die für das Auslösen des AlarmEvent-Ereignisses zuständig ist.


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


Im folgenden Beispiel wird die Set-Methode definiert, die die Logik zum Auslösen des Ereignisses durch Aufrufen der OnAlarmEvent-Methode, enthält. Wenn die Stunden und Minuten des Alarmzeitpunkts den Stunden und Minuten der aktuellen Uhrzeit entsprechen, instanziiert die Set-Methode ein AlarmEventArgs-Objekt und gibt den Zeitpunkt an, zu dem der Alarm ausgelöst wurde. Nachdem die Ereignishandler ausgeführt wurden, wird der Wert der Snooze-Eigenschaft überprüft. Wenn Snooze gleich false ist, sollen keine weiteren Alarmereignisse ausgelöst werden, und die Set-Methode kann beendet werden. Wenn Snooze gleich true ist, wird der Zeitpunkt, zu dem der Alarm ausgelöst werden soll, um den Wert der Interval-Eigenschaft erhöht.


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);
      }
   }
} 


Im folgenden Beispiel finden Sie den vollständigen Quellcode für die Alarm-Klasse.


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);
   }  
}


Community-Beiträge

Anzeigen: