Richtlinien für die Verwendung von Ereignissen

Die folgenden Regeln dienen als Richtlinie für die Verwendung von Ereignissen:

  • Wählen Sie für das Ereignis einen Namen gemäß den empfohlenen Richtlinien für die Benennung von Ereignissen.

  • Wenn Sie in der Dokumentation auf Ereignisse verweisen, verwenden Sie die Formulierung "an event was raised" ("ein Ereignis wurde ausgelöst"), und nicht "an event was fired" oder "an event was triggered".

  • In Sprachen, die das void-Schlüsselwort unterstützen, verwenden Sie den Rückgabetyp void für Ereignishandler, wie im folgenden C#-Codebeispiel gezeigt.

    public delegate void MouseEventHandler(object sender, MouseEventArgs e);
    
  • Verwenden Sie Ereignisdatenklassen mit strikter Typbindung, wenn ein Ereignis wichtige Daten, wie die Koordinaten eines Mausklicks, übermittelt.

  • Ereignisklassen sollten die System.EventArgs-Klasse erweitern, wie im folgenden Beispiel gezeigt.

    Public Class MouseEventArgs
       Inherits EventArgs 
       ' Code for the class goes here.
    End Class
    [C#]
    public class MouseEvent: EventArgs {}
    
  • Verwenden Sie eine virtuelle protected (in Visual Basic Protected)-Methode, um die einzelnen Ereignisse auszulösen. Diese Technik ist nicht für versiegelte Klassen geeignet, da aus diesen keine Klassen abgeleitet werden können. Diese Technik ermöglicht es, dass eine abgeleitete Klasse das Ereignis durch Überschreiben behandeln kann. Dies ist in Situationen, in denen der Entwickler eine abgeleitete Klasse erstellt, natürlicher als die Verwendung von Delegaten. Der Name der Methode hat das Format OnEventName, wobei EventName der Name des ausgelösten Ereignisses ist. Beispiel:

    Public Class Button
       Private onClickHandler As ButtonClickHandler  
       Protected Overridable Sub OnClick(e As ClickEventArgs)
          ' Call the delegate if non-null.
          If Not (onClickHandler Is Nothing) Then
             onClickHandler(Me, e)
          End If 
       End Sub
    End Class
    
    [C#]
    public class Button 
    {
       ButtonClickHandler onClickHandler;
    
       protected virtual void OnClick(ClickEventArgs e) 
       {
          // Call the delegate if non-null.
          if (onClickHandler != null)
                onClickHandler(this, e);      
       }
    }
    

    Die abgeleitete Klasse hat auch die Möglichkeit, während der Verarbeitung von OnEventName nicht die Basisklasse aufzurufen. Treffen Sie entsprechende Vorkehrungen hierfür, indem Sie keinerlei Verarbeitung in die OnEventName-Methode aufnehmen, die für das ordnungsgemäße Funktionieren der Basisklasse erforderlich ist.

  • Gehen Sie davon aus, dass ein Ereignishandler jeden beliebigen Code enthalten kann. Klassen sollten unterstützen, dass der Ereignishandler nahezu jede beliebige Operation ausführen kann. Außerdem sollte das Objekt in jedem Fall einen entsprechenden Status annehmen, nachdem das Ereignis ausgelöst worden ist. Überlegen Sie, ob Sie einen try/finally-Block an dem Punkt im Code verwenden sollten, an der das Ereignis ausgelöst wird. Da der Entwickler eine Rückruffunktion für das Objekt festlegen kann, um andere Aktionen auszuführen, gehen Sie von keiner Annahme hinsichtlich des Objektstatus aus, wenn die Steuerung wieder zu dem Punkt zurückkehrt, an dem das Ereignis ausgelöst wurde. Beispiel:

    Public Class Button
       Private onClickHandler As ButtonClickHandler
       Protected Sub DoClick()
          ' Paint button in indented state.      
          PaintDown()
          Try
             ' Call event handler.
             OnClick()      
          Finally
             ' Window might be deleted in event handler.
             If Not (windowHandle Is Nothing) Then
                ' Paint button in normal state.
                PaintUp()
             End If 
          End Try
       End Sub
       Protected Overridable Sub OnClick(e As ClickEvent)
          If Not (onClickHandler Is Nothing) Then
             onClickHandler(Me, e)
          End If
       End Sub
    End Class
    [C#]
    public class Button
    {
       ButtonClickHandler onClickHandler;
    
       protected void DoClick()
       {
          // Paint button in indented state.
          PaintDown();
             try
          {
             // Call event handler.
             OnClick();         
          }
          finally
          {
             // Window might be deleted in event handler.
             if (windowHandle != null)
                // Paint button in normal state.
                PaintUp();            
          }
       }
    
       protected virtual void OnClick(ClickEvent e)
       {
          if (onClickHandler != null)
             onClickHandler(this, e);
       }
    }
    
  • Verwenden oder erweitern Sie die System.ComponentModel.CancelEventArgs-Klasse, um dem Entwickler die Steuerung der Ereignisse eines Objekts zu ermöglichen. So löst beispielsweise das TreeView-Steuerelement ein BeforeLabelEdit aus, wenn der Benutzer beginnt, eine Knotenbezeichnung zu bearbeiten. Das folgende Codebeispiel veranschaulicht, wie der Entwickler mit diesem Ereignis die Bearbeitung eines Knotens unterbinden kann.

    Public Class Form1
       Inherits Form
       Private treeView1 As New TreeView() 
    
       Sub treeView1_BeforeLabelEdit(source As Object, e As NodeLabelEditEventArgs)
          e.CancelEdit = True
       End Sub
    End Class
    [C#]
    public class Form1: Form 
    {
       TreeView treeView1 = new TreeView();
    
       void treeView1_BeforeLabelEdit(object source, 
          NodeLabelEditEventArgs e) 
       {
          e.CancelEdit = true;
       }
    }
    

    Beachten Sie, dass in diesem Fall keine Fehlermeldung an den Benutzer ausgegeben wird. Die Bezeichnung ist schreibgeschützt.

    Abbruchereignisse sind nicht in Fällen geeignet, in denen der Entwickler die Operation abbrechen und eine Ausnahme zurückgeben würde. Lösen Sie in diesen Fällen eine Ausnahme innerhalb des Ereignishandlers aus, um die Operation abzubrechen. Vielleicht möchte der Benutzer z. B. Validierungslogik in ein Bearbeitungssteuerelement schreiben, wie unten veranschaulicht.

    Public Class Form1
       Inherits Form
       Private edit1 As EditBox = New EditBox() 
    
       Sub TextChanging(source As Object, e As EventArgs)
          Throw New RuntimeException("Invalid edit")
       End Sub
    End Class
    [C#]
    public class Form1: Form 
    {
       EditBox edit1 = new EditBox();
    
       void TextChanging(object source, EventArgs e) 
       {
          throw new RuntimeException("Invalid edit");
       }
    

Siehe auch

Entwurfsrichtlinien für die Entwicklung von Klassenbibliotheken | Richtlinien für die Benennung von Ereignissen | Richtlinien für die Verwendung von Klassenmembern