Wie kann ich mein eigenes Event in C # erstellen?

122

Wie kann ich mein eigenes Event in C # erstellen?

Gold
quelle

Antworten:

217

Hier ist ein Beispiel für das Erstellen und Verwenden eines Ereignisses mit C #

using System;

namespace Event_Example
{
    //First we have to define a delegate that acts as a signature for the
    //function that is ultimately called when the event is triggered.
    //You will notice that the second parameter is of MyEventArgs type.
    //This object will contain information about the triggered event.
    public delegate void MyEventHandler(object source, MyEventArgs e);

    //This is a class which describes the event to the class that recieves it.
    //An EventArgs class must always derive from System.EventArgs.
    public class MyEventArgs : EventArgs
    {
        private string EventInfo;
        public MyEventArgs(string Text)
        {
            EventInfo = Text;
        }
        public string GetInfo()
        {
            return EventInfo;
        }
    }

    //This next class is the one which contains an event and triggers it
    //once an action is performed. For example, lets trigger this event
    //once a variable is incremented over a particular value. Notice the
    //event uses the MyEventHandler delegate to create a signature
    //for the called function.
    public class MyClass
    {
        public event MyEventHandler OnMaximum;
        private int i;
        private int Maximum = 10;
        public int MyValue
        {
            get
            {
                return i;
            }
            set
            {
                if(value <= Maximum)
                {
                    i = value;
                }
                else
                {
                    //To make sure we only trigger the event if a handler is present
                    //we check the event to make sure it's not null.
                    if(OnMaximum != null)
                    {
                        OnMaximum(this, new MyEventArgs("You've entered " +
                            value.ToString() +
                            ", but the maximum is " +
                            Maximum.ToString()));
                    }
                }
            }
        }
    }

    class Program
    {
        //This is the actual method that will be assigned to the event handler
        //within the above class. This is where we perform an action once the
        //event has been triggered.
        static void MaximumReached(object source, MyEventArgs e)
        {
            Console.WriteLine(e.GetInfo());
        }

        static void Main(string[] args)
        {
            //Now lets test the event contained in the above class.
            MyClass MyObject = new MyClass();
            MyObject.OnMaximum += new MyEventHandler(MaximumReached);

            for(int x = 0; x <= 15; x++)
            {
                MyObject.MyValue = x;
            }

            Console.ReadLine();
        }
    }
}
Gary Willoughby
quelle
4
Nachdem ich hundert Erklärungen besucht hatte, half mir dies schließlich zu verstehen. SE hatte recht, Stellen sind auch nach einigen Jahren noch relevant.
1
{Meh!} Ich vergesse immer , den eventTeil für die Klasse zu schreiben .
JP2-Code
51

Ich habe eine vollständige Diskussion über Ereignisse und Delegierte in meinem Veranstaltungsartikel . Für die einfachste Art von Ereignis können Sie einfach ein öffentliches Ereignis deklarieren, und der Compiler erstellt sowohl ein Ereignis als auch ein Feld, um die Abonnenten zu verfolgen:

public event EventHandler Foo;

Wenn Sie eine kompliziertere Abonnement- / Abmeldelogik benötigen, können Sie dies explizit tun:

public event EventHandler Foo
{
    add
    {
        // Subscription logic here
    }
    remove
    {
        // Unsubscription logic here
    }
}
Jon Skeet
quelle
1
Ich war mir nicht sicher, wie ich das Ereignis aus meinem Code aufrufen sollte, aber es stellt sich als sehr offensichtlich heraus. Sie nennen es einfach wie eine Methode, die einen Absender und ein EventArgs-Objekt übergibt. [dh. if (fooHappened) Foo (Absender, eventArgs); ]
Richard Garside
2
@ Richard: Nicht ganz; Sie müssen den Fall behandeln, in dem keine Abonnenten vorhanden sind, sodass die Delegatenreferenz null ist.
Jon Skeet
Ich freue mich auf das C # 4-Update zu thread-sicheren Ereignissen in dem Artikel, den Sie verlinkt haben. Wirklich tolle Arbeit, @JonSkeet!
Kdbanman
20

Sie können ein Ereignis mit dem folgenden Code deklarieren:

public event EventHandler MyOwnEvent;

Bei Bedarf kann ein benutzerdefinierter Delegattyp anstelle von EventHandler verwendet werden.

Detaillierte Informationen / Tutorials zur Verwendung von Ereignissen in .NET finden Sie im Artikel Events Tutorial (MSDN).

Brann
quelle
4

Dazu müssen wir die drei Komponenten kennen

  1. der Ort, für den verantwortlich ist firing the Event
  2. der Ort, für den verantwortlich ist responding to the Event
  3. das Ereignis selbst

    ein. Veranstaltung

    b .EventArgs

    c. EventArgs-Aufzählung

Jetzt können Sie ein Ereignis erstellen, das ausgelöst wird, wenn eine Funktion aufgerufen wird

Aber ich habe die Reihenfolge, um dieses Problem so zu lösen: Ich verwende die Klasse, bevor ich sie erstelle

  1. der Ort, für den verantwortlich ist responding to the Event

    NetLog.OnMessageFired += delegate(object o, MessageEventArgs args) 
    {
            // when the Event Happened I want to Update the UI
            // this is WPF Window (WPF Project)  
            this.Dispatcher.Invoke(() =>
            {
                LabelFileName.Content = args.ItemUri;
                LabelOperation.Content = args.Operation;
                LabelStatus.Content = args.Status;
            });
    };

NetLog ist eine statische Klasse, die ich später erläutern werde

Der nächste Schritt ist

  1. der Ort, für den verantwortlich ist firing the Event

    //this is the sender object, MessageEventArgs Is a class I want to create it  and Operation and Status are Event enums
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Started));
    downloadFile = service.DownloadFile(item.Uri);
    NetLog.FireMessage(this, new MessageEventArgs("File1.txt", Operation.Download, Status.Finished));

der dritte Schritt

  1. das Ereignis selbst

Ich habe The Event in einer Klasse namens NetLog verzerrt

public sealed class NetLog
{
    public delegate void MessageEventHandler(object sender, MessageEventArgs args);

    public static event MessageEventHandler OnMessageFired;
    public static void FireMessage(Object obj,MessageEventArgs eventArgs)
    {
        if (OnMessageFired != null)
        {
            OnMessageFired(obj, eventArgs);
        }
    }
}

public class MessageEventArgs : EventArgs
{
    public string ItemUri { get; private set; }
    public Operation Operation { get; private set; }
    public Status Status { get; private set; }

    public MessageEventArgs(string itemUri, Operation operation, Status status)
    {
        ItemUri = itemUri;
        Operation = operation;
        Status = status;
    }
}

public enum Operation
{
    Upload,Download
}

public enum Status
{
    Started,Finished
}

enthält diese Klasse jetzt the Event, EventArgsund EventArgs Enumsund the functionverantwortlich für die Veranstaltung zum Brennen

Entschuldigung für diese lange Antwort

Basheer AL-MOMANI
quelle
Der Hauptunterschied bei dieser Antwort besteht darin, dass das Ereignis statisch ist, wodurch Ereignisse empfangen werden können, ohne dass ein Verweis auf das Objekt erforderlich ist, das das Ereignis ausgelöst hat. Ideal zum Abonnieren von Ereignissen aus mehreren unabhängigen Steuerelementen.
Radderz