Gewusst wie: Veröffentlichen von Ereignissen, die den .NET Framework-Richtlinien entsprechen (C#-Programmierhandbuch)
Das folgende Verfahren veranschaulicht, wie Sie den Klassen und Strukturen Ereignisse hinzufügen, die dem Standardmuster von .NET Framework entsprechen. 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);
Tipp
.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
(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 für die benutzerdefinierten Daten mit einem Bereich, der sowohl für die Herausgeber- als auch die Abonnentenklasse sichtbar ist. Fügen Sie dann die erforderlichen 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; } } }
(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);
Deklarieren Sie das Ereignis in der Veröffentlichungsklasse mit einem der folgenden Schritte.
Wenn Sie über keine benutzerdefinierte EventArgs-Klasse verfügen, entspricht der Ereignistyp dem nicht generischen EventHandler-Delegaten. Sie müssen den Delegaten nicht deklarieren, da er bereits in dem standardmäßig in C#-Projekten enthaltenen System-Namespace deklariert ist. Fügen Sie der Herausgeberklasse folgenden Code hinzu:
public event EventHandler RaiseCustomEvent;
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 in der Veröffentlichungsklasse, und verwenden Sie den Delegaten aus Schritt 2 als Typ.
public event CustomEventHandler RaiseCustomEvent;
Wenn Sie die generische Version verwenden, benötigen Sie keinen benutzerdefinierten Delegaten. Stattdessen geben Sie in der Veröffentlichungsklasse 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 des Ereignistyps 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
Referenz
Ereignisse (C#-Programmierhandbuch)
Delegaten (C#-Programmierhandbuch)