Behandeln von Ereignissen

Um ein Ereignis in einer Anwendung zu verarbeiten, müssen Sie einen Ereignishandler (eine Methode für die Ereignisbehandlung) bereitstellen, der als Reaktion auf das Ereignis Programmlogik ausführt, und den Ereignishandler bei der Ereignisquelle registrieren. Dieser Prozess wird als Ereignisverknüpfung bezeichnet. In den visuellen Designern für Windows Forms und Web Forms sind RAD-Tools (Rapid Application Development) verfügbar, die die Details der Ereignisverknüpfung vereinfachen bzw. vor dem Benutzer verbergen.

In diesem Thema wird das allgemeine Muster zur Behandlung von Ereignissen beschrieben. Eine Übersicht über das Ereignismodell in .NET Framework finden Sie unter Ereignisse und Delegaten. Weitere Informationen über das Ereignismodell in Windows Forms finden Sie unter Gewusst wie: Verarbeiten von Ereignissen in einer Windows Forms-Anwendung. Weitere Informationen über das Ereignismodell in Web Forms finden Sie unter Gewusst wie: Verarbeiten von Ereignissen in einer Web Forms-Anwendung.

Das Ereignismuster

Die Details der Ereignisverknüpfung unterscheiden sich in Windows Forms und in Web Forms, da durch verschiedene RAD-Tools unterschiedliche Supportebenen bereitgestellt werden. Beide Szenarien folgen aber demselben Ereignismuster, das die folgenden Merkmale aufweist:

  • Eine Klasse, die ein Ereignis mit dem Namen EventName auslöst, hat den folgenden Member:
Public Event EventName As EventNameEventHandler
public event EventNameEventHandler EventName;
public:
    event EventNameEventHandler^ EventName;
  • Der Ereignisdelegat für das EventName-Ereignis ist EventNameEventHandler mit der folgenden Signatur:
Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
delegate void EventNameEventHandler(Object^ sender, EventNameEventArgs^ e);

Um das EventName-Ereignis zu verarbeiten, muss der Ereignishandler die gleiche Signatur wie der Ereignisdelegat haben:

Sub EventHandler(sender As Object, e As EventNameEventArgs)
End Sub
void EventHandler(object sender, EventNameEventArgs e) {}
void EventHandler(Object^ sender, EventNameEventArgs^ e) {}

Hinweis

In .NET Framework hat ein Ereignisdelegat die Bezeichnung EventNameEventHandler, während sich der Begriff Ereignishandler in der Dokumentation auf eine Methode für die Ereignisbehandlung bezieht.Der Grund für dieses Benennungsschema liegt darin, dass ein EventNameEventHandler-Delegat auf den Ereignishandler (die Methode) verweist, der das Ereignis behandelt.

Wenn ein Ereignis keine zugeordneten Daten besitzt, verwendet die Klasse, die das Ereignis auslöst, System.EventHandler als Delegat und System.EventArgs für die Ereignisdaten. Ereignisse, denen Daten zugeordnet sind, verwenden Klassen, die von EventArgs für den Ereignisdatentyp abgeleitet sind, und den zugeordneten Ereignisdelegattyp. Wenn Sie z. B. ein MouseUp-Ereignis in einer Windows Forms-Anwendung behandeln möchten, lautet die Ereignisdatenklasse MouseEventArgs, und der Ereignisdelegat ist MouseEventHandler. Beachten Sie, dass verschiedene Mausereignisse eine allgemeine Klasse für Ereignisdaten und einen allgemeinen Ereignisdelegaten verwenden, sodass das Benennungsschema nicht genau mit der oben beschriebenen Konvention übereinstimmt. Für die Mausereignisse muss der Ereignishandler über die folgende Signatur verfügen:

Sub Mouse_Moved(sender As Object, e As MouseEventArgs)
End Sub
void Mouse_Moved(object sender, MouseEventArgs e){}
void Mouse_Moved(Object^ sender, MouseEventArgs^ e){}

Die Parameter für den Absender und das Ereignisargument übergeben zusätzliche Details über das Mausereignis an den Ereignishandler. Das sender-Objekt gibt an, was das Ereignis ausgelöst hat. Der MouseEventArgs-Parameter stellt Details über die Mausbewegung bereit, die das Ereignis ausgelöst hat. Viele Ereignisquellen stellen zusätzliche Daten für das Ereignis bereit, und viele Ereignishandler verwenden ereignisspezifische Daten bei der Verarbeitung des Ereignisses. Ein Beispiel, das das Auslösen und Behandeln von Ereignissen mit ereignisspezifischen Daten veranschaulicht, finden Sie unter Gewusst wie: Auslösen und Behandeln von Ereignissen.

Hinweis

Ereignisse werden auch außerhalb des Kontexts von Benutzeroberflächen (UI - User Interfaces) ausgelöst, und .NET Framework enthält viele nicht UI-bezogene Klassen, die Ereignisse auslösen.Alle Ereignisse folgen jedoch dem hier beschriebenen Muster.

Informationen über das Auslösen von Ereignissen aus einer Klasse finden Sie unter Auslösen eines Ereignisses.

Statische und dynamische Ereignisse

Der .NET Framework ermöglicht es Abonnenten, sich entweder statisch oder dynamisch für Ereignisbenachrichtigungen zu registrieren. Statische Ereignishandler sind für die gesamte Lebensdauer der Klasse gültig, deren Ereignisse sie behandeln. Dies ist die am weitesten verbreitete Methode zur Behandlung von Ereignissen. Dynamische Ereignishandler werden bei der Programmausführung explizit aktiviert und deaktiviert. Dies erfolgt in der Regel als Reaktion auf eine bedingte Programmlogik. So können sie beispielsweise verwendet werden, wenn Ereignisbenachrichtigungen nur unter bestimmten Bedingungen erforderlich sind, oder wenn eine Anwendung mehrere Ereignishandler bereitstellt und über die Laufzeitbedingungen definiert wird, welcher davon verwendet wird.

Die EventInfo.AddEventHandler-Methode fügt dynamische Ereignishandler hinzu, und die EventInfo.RemoveEventHandler-Methode deaktiviert sie. Einzelne Sprachen stellen zudem eigene Features zum dynamischen Behandeln von Ereignissen bereit. Im folgenden Beispiel wird eine TemperatureMonitor-Klasse definiert, die ein TemperatureTheshold-Ereignis auslöst, wenn die Temperatur einen vordefinierten Schwellenwert erreicht. Ein Ereignishandler, der dieses Ereignis abonniert, wird während der Programmausführung aktiviert und deaktiviert.

public class TemperatureEventArgs : Inherits EventArgs
   Private oldTemp As Decimal
   Private newTemp As Decimal

   Public ReadOnly Property OldTemperature As Decimal
      Get
         Return Me.oldTemp
      End Get   
   End Property

   Public ReadOnly Property NewTemperature As Decimal
      Get
         Return Me.newTemp
      End Get
   End Property

   Public Sub New(oldTemp As Decimal, newTemp As Decimal)
      Me.oldTemp = oldTemp
      Me.newTemp = newTemp   
   End Sub
End Class

Public Delegate Sub TemperatureEventHandler(sender As Object, _
                                            ev As TemperatureEventArgs)

Public Class TemperatureMonitor
   Private currentTemperature As Decimal
   Private threshholdTemperature As Decimal

   Public Event TemperatureThreshold As TemperatureEventHandler 

   Public Sub New(threshHold As Decimal)
      Me.threshholdTemperature = threshHold
   End Sub

   Public Sub SetTemperature(newTemperature As Decimal)
      If (Me.currentTemperature > threshholdTemperature And _
         newTemperature <= Me.threshholdTemperature) Or _
         (Me.CurrentTemperature < Me.threshholdTemperature And _
             newTemperature >= Me.threshholdTemperature) Then
         OnRaiseTemperatureEvent(newTemperature)
      End If
      Me.currentTemperature = newTemperature
   End Sub

   Public Function GetTemperature() As Decimal
      Return Me.currentTemperature
   End Function

   Protected Overridable Sub OnRaiseTemperatureEvent(newTemperature As Decimal)
      RaiseEvent TemperatureThreshold(Me, New TemperatureEventArgs(Me.currentTemperature, _ 
                                       newTemperature))
   End Sub                                       
End Class

Public Module Example
   Public Sub Main()
      Dim tempMon As New TemperatureMonitor(32d)
      tempMon.SetTemperature(33)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(32)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())

      ' Add event handler dynamically using Visual Basic syntax.
      AddHandler tempMon.TemperatureThreshold, AddressOf TempMonitor

      tempMon.SetTemperature(33)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(34)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())
      tempMon.SetTemperature(32)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _
                        tempMon.GetTemperature())

      ' Remove event handler dynamically using Visual Basic syntax.
      RemoveHandler tempMon.TemperatureThreshold, AddressOf TempMonitor

      tempMon.SetTemperature(31)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _ 
                        tempMon.GetTemperature())
      tempMon.SetTemperature(35)
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", _ 
                        tempMon.GetTemperature())
   End Sub

   Private Sub TempMonitor(sender As Object, e As TemperatureEventArgs)
      Console.WriteLine("   ***Warning: Temperature is changing from {0} to {1}.", _ 
                        e.OldTemperature, e.NewTemperature)
   End Sub 
End Module
' The example displays the following output:
'       Current temperature is 33 degrees Fahrenheit.
'       Current temperature is 32 degrees Fahrenheit.
'       Current temperature is 33 degrees Fahrenheit.
'       Current temperature is 34 degrees Fahrenheit.
'          ***Warning: Temperature is changing from 34 to 32.
'       Current temperature is 32 degrees Fahrenheit.
'       Current temperature is 31 degrees Fahrenheit.
'       Current temperature is 35 degrees Fahrenheit.
using System;

public class TemperatureEventArgs : EventArgs
{
   private decimal oldTemp;
   private decimal newTemp;

   public decimal OldTemperature
   {
      get { return this.oldTemp; }
   }

   public decimal NewTemperature
   {
      get { return this.newTemp; }
   }

   public TemperatureEventArgs(decimal oldTemp, decimal newTemp)
   {
      this.oldTemp = oldTemp;
      this.newTemp = newTemp;   
   }
}

public delegate void TemperatureEventHandler(object sender, TemperatureEventArgs ev);

public class TemperatureMonitor
{
   private decimal currentTemperature;
   private decimal threshholdTemperature;

   public event TemperatureEventHandler TemperatureThreshold; 

   public TemperatureMonitor(decimal threshhold)
   {
      this.threshholdTemperature = threshhold;
   }

   public void SetTemperature(decimal newTemperature)
   {
      if ( (this.currentTemperature > this.threshholdTemperature && 
           newTemperature <= this.threshholdTemperature) ||
           (this.currentTemperature < this.threshholdTemperature &&
           newTemperature >= this.threshholdTemperature) )
         OnRaiseTemperatureEvent(newTemperature);
      this.currentTemperature = newTemperature;
   }

   public decimal GetTemperature()
   {
      return this.currentTemperature;
   }

   protected virtual void OnRaiseTemperatureEvent(decimal newTemperature)
   {
      // Raise the event if it has subscribers.
      if (TemperatureThreshold != null)
         TemperatureThreshold(this, new TemperatureEventArgs(this.currentTemperature, 
                               newTemperature));
   }
}

public class Example
{
   public static void Main()
   {
      Example ex = new Example();
      ex.MonitorTemperatures();
   }

   public void MonitorTemperatures()
   {
      TemperatureMonitor tempMon = new TemperatureMonitor(32);
      tempMon.SetTemperature(33);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(32);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
                        tempMon.GetTemperature());

      // Add event handler dynamically using C# syntax.
      tempMon.TemperatureThreshold += this.TempMonitor;

      tempMon.SetTemperature(33);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(34);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(32);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.",
                        tempMon.GetTemperature());

      // Remove event handler dynamically using C# syntax.
      tempMon.TemperatureThreshold -= this.TempMonitor;

      tempMon.SetTemperature(31);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
      tempMon.SetTemperature(35);
      Console.WriteLine("Current temperature is {0} degrees Fahrenheit.", 
                        tempMon.GetTemperature());
   }

   private void TempMonitor(object sender, TemperatureEventArgs e)
   {
      Console.WriteLine("   ***Warning: Temperature is changing from {0} to {1}.", 
                        e.OldTemperature, e.NewTemperature);
   } 
}
// The example displays the following output:
//       Current temperature is 33 degrees Fahrenheit.
//       Current temperature is 32 degrees Fahrenheit.
//       Current temperature is 33 degrees Fahrenheit.
//       Current temperature is 34 degrees Fahrenheit.
//          ***Warning: Temperature is changing from 34 to 32.
//       Current temperature is 32 degrees Fahrenheit.
//       Current temperature is 31 degrees Fahrenheit.
//       Current temperature is 35 degrees Fahrenheit.

Siehe auch

Aufgaben

Gewusst wie: Verarbeiten von Ereignissen in einer Web Forms-Anwendung

Gewusst wie: Verarbeiten von Ereignissen in einer Windows Forms-Anwendung

Konzepte

Ereignisse und Delegaten

Auslösen eines Ereignisses

Weitere Ressourcen

Behandeln und Auslösen von Ereignissen