Gewusst wie: Veröffentlichen von Ereignissen, die den .NET Framework-Richtlinien entsprechen (C#-Programmierhandbuch)

Aktualisiert: November 2007

Die folgende Prozedur zeigt, wie Sie Ihren Klassen und Strukturen Ereignisse hinzufügen, die dem Standardmuster von .NET Framework folgen. Sämtliche Ereignisse in der .NET Framework-Klassenbibliothek basieren auf dem EventHandler-Delegat, der folgendermaßen definiert ist:

public delegate void EventHandler(object sender, EventArgs e);
Hinweis:

.NET Framework 2.0 führt eine generische Version dieses Delegaten ein, EventHandler<TEventArgs>. Die folgenden Beispiele zeigen die Verwendung beider Versionen.

Grundsätzlich können Ereignisse in benutzerdefinierten Klassen auf jedem gültigen Delegattyp basieren, einschließlich Delegaten, die einen Wert zurückgeben. Im Allgemeinen wird jedoch empfohlen, Ereignisse auf dem .NET Framework-Muster zu basieren, indem Sie EventHandler verwenden, wie im folgenden Beispiel gezeigt:

So veröffentlichen Sie Ereignisse auf Basis des EventHandler-Musters

  1. (Wenn Sie keine benutzerdefinierten Daten mit dem Ereignis senden müssen, können Sie diesen Schritt überspringen und mit Schritt 3a fortfahren.) Deklarieren Sie die Klasse mit einem Bereich, der sowohl für die Herausgeber- als auch die Abonnentenklasse sichtbar ist, und fügen Sie die gewünschten Member zum Speichern der benutzerdefinierten Ereignisdaten hinzu. In diesem Beispiel wird eine einfache Zeichenfolge zurückgegeben.

    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string s)
        {
            msg = s;
        }
        private string msg;
        public string Message
        {
            get { return msg; }
        } 
    }
    
  2. (Wenn Sie die generische Version von EventHandler<TEventArgs> verwenden, können Sie diesen Schritt überspringen.) Deklarieren Sie einen Delegaten in der Veröffentlichungsklasse. Weisen Sie ihm einen Namen zu, der auf EventHandler endet. Der zweite Parameter gibt den benutzerdefinierten EventArgs-Typ an.

    public delegate void CustomEventHandler(object sender, CustomEventArgs a);
    
  3. Deklarieren Sie das Ereignis in der Veröffentlichungsklasse mit einem der folgenden Schritte.

    1. Wenn Sie über keine benutzerdefinierte EventArgs-Klasse verfügen, entspricht der Ereignistyp dem nicht generischen EventHandler-Delegaten. Sie müssen sie nicht deklarieren, da sie bereits in dem standardmäßig in C#-Projekten enthaltenen System-Namespace deklariert ist:

      public event EventHandler RaiseCustomEvent;
      
    2. Wenn Sie die nicht generische Version von EventHandler verwenden und über eine benutzerdefinierte Klasse verfügen, die von EventArgs abgeleitet wurde, deklarieren Sie das Ereignis innerhalb der Veröffentlichungsklasse, und verwenden Sie den Delegaten als Typ:

      class Publisher
      {
          public event CustomEventHandler RaiseCustomEvent;
      }
      
    3. Wenn Sie die generische Version verwenden, benötigen Sie keinen benutzerdefinierten Delegaten. Stattdessen geben Sie den Ereignistyp mit EventHandler<CustomEventArgs> an, mit dem Namen Ihrer Klasse zwischen den spitzen Klammern.

      public event EventHandler<CustomEventArgs> RaiseCustomEvent;
      

Beispiel

Das folgende Beispiel veranschaulicht die oben beschriebenen Schritte anhand einer benutzerdefinierten EventArgs-Klasse und dem Ereignistyp EventHandler<TEventArgs>.

namespace DotNetEvents
{
    using System;
    using System.Collections.Generic;

    // Define a class to hold custom event info
    public class CustomEventArgs : EventArgs
    {
        public CustomEventArgs(string s)
        {
            message = s;
        }
        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }

    // Class that publishes an event
    class Publisher
    {

        // Declare the event using EventHandler<T>
        public event EventHandler<CustomEventArgs> RaiseCustomEvent;

        public void DoSomething()
        {
            // Write some code that does something useful here
            // then raise the event. You can also raise an event
            // before you execute a block of code.
            OnRaiseCustomEvent(new CustomEventArgs("Did something"));

        }

        // Wrap event invocations inside a protected virtual method
        // to allow derived classes to override the event invocation behavior
        protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
        {
            // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.
            EventHandler<CustomEventArgs> handler = RaiseCustomEvent;

            // Event will be null if there are no subscribers
            if (handler != null)
            {
                // Format the string to send inside the CustomEventArgs parameter
                e.Message += String.Format(" at {0}", DateTime.Now.ToString());

                // Use the () operator to raise the event.
                handler(this, e);
            }
        }
    }

    //Class that subscribes to an event
    class Subscriber
    {
        private string id;
        public Subscriber(string ID, Publisher pub)
        {
            id = ID;
            // Subscribe to the event using C# 2.0 syntax
            pub.RaiseCustomEvent += HandleCustomEvent;
        }

        // Define what actions to take when the event is raised.
        void HandleCustomEvent(object sender, CustomEventArgs e)
        {
            Console.WriteLine(id + " received this message: {0}", e.Message);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Publisher pub = new Publisher();
            Subscriber sub1 = new Subscriber("sub1", pub);
            Subscriber sub2 = new Subscriber("sub2", pub);

            // Call the method that raises the event.
            pub.DoSomething();

            // Keep the console window open
            Console.WriteLine("Press Enter to close this window.");
            Console.ReadLine();

        }
    }
}

Siehe auch

Konzepte

C#-Programmierhandbuch

Ereignisentwurf

Referenz

Ereignisse (C#-Programmierhandbuch)

Delegaten (C#-Programmierhandbuch)

Delegate