Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Benutzerdefinierte Ereignisse | Interaktive GUI
Fortgeschrittenes C# mit .NET
course content

Kursinhalt

Fortgeschrittenes C# mit .NET

Fortgeschrittenes C# mit .NET

1. Einführung in die Desktop-Entwicklung mit .NET
2. Interaktive GUI
3. Threading
4. Generics & Reflection

book
Benutzerdefinierte Ereignisse

Im vorherigen Kapitel haben wir gelernt, wie man Methoden an Ereignishandler bindet, aber ist es möglich, unsere eigenen Ereignisse zu erstellen? Ja, tatsächlich ist es auch ziemlich einfach.

Ein Ereignissystem besteht aus zwei Teilen: Der Publisher-Klasse und der Subscriber-Klasse. Es gibt immer eine einzelne Publisher-Klasse für ein Ereignis, jedoch kann es mehrere Subscriber-Klassen geben.

Eine Publisher-Klasse enthält den Ereignishandler-Delegaten für das Ereignis und eine Methode, um diesen Delegaten bei Bedarf aufzurufen.

Eine Klasse wird in diesem Kontext als Subscriber-Klasse bezeichnet, wenn sie eine Methode an den Ereignishandler der Publisher-Klasse abonniert.

Das folgende Diagramm zeigt den Prozessablauf eines Ereignissystems:

Wir werden ein einfaches Ereignissystem ausgehend vom Standardprojekt erstellen. Innerhalb der C#-Datei erstellen wir zuerst eine neue Klasse namens CounterEvent, die die Publisher-Klasse darstellen wird, und sie wird eine EventHandler-Instanz haben, die wir mit dem bereits vorhandenen EventHandler-Typ erstellen:

cs

index

copy
123
public class CounterEvent { public event EventHandler AtTensMultiple; }

Diese Klasse benötigt auch eine Methode, um den Ereignishandler bei Bedarf aufzurufen. Wir können ein Ereignis erstellen, das immer dann ausgelöst wird, wenn die Bedingung count % 10 == 0 erfüllt ist, wobei count die Anzahl der Male ist, die der Benutzer auf den CounterBtn geklickt hat. Definieren wir zuerst die Aufrufmethode innerhalb des CounterEvent, wir nennen sie CountCheck, weil sie im Grunde den Wert von count jedes Mal überprüft, wenn sie aufgerufen wird, und AtTensMultiple aufruft, wenn die Bedingung erfüllt ist.

cs

index

copy
12345678910111213
public class CounterEvent { public event EventHandler? AtTensMultiple; public void CountCheck(int count) { if(count % 10 == 0) { EventHandler? handler = AtTensMultiple; if(handler) { AtTensMultiple(this, new EventArgs()); } } } }

Hier wird das this-Argument übergeben, um den sender darzustellen, und new EventArgs() stellt eine neue Instanz einer leeren Klasse dar. Wir können Daten in die Methoden übergeben, die sich beim Ereignishandler angemeldet haben, wenn der Ereignishandler aufgerufen wird, indem wir dieses zweite Argument verwenden. Da wir jedoch EventArgs übergeben, was eine leere Klasse ist, werden keine Daten übergeben. Wir werden gleich sehen, wie man auf diese Weise Daten übergibt.

Jetzt, da die Aufrufmethode definiert ist, ist unsere Publisher-Klasse so gut wie fertig. Wir müssen noch zwei Dinge tun:

  1. Eine Instanz der Publisher-Klasse erstellen;
  2. Die Aufrufmethode aufrufen, um sie funktionsfähig zu machen;

Also, zuerst werde ich eine Instanz innerhalb der MainPage-Klasse erstellen:

cs

index

copy
1
public static CounterEvent counter = new CounterEvent();

Und jetzt rufen wir diese Methode innerhalb von OnCounterClicked auf, damit sie bei jedem Klick des Benutzers auf den Button eine Überprüfung durchführt.

cs

index

copy
12345678910
private void OnCounterClicked(object? sender, new EventArgs e) { count++; if(count == 0) CounterBtn.Text = $"Clicked {count} time"; else CounterBtn.Text = $"Clicked {count} times"; counter.CounterCheck(count); }

Jetzt, da unser Ereignis funktionsfähig ist, sind wir bereit, eine Methode an den Ereignishandler zu binden. Ich werde eine neue Methode namens Reformat erstellen, die einfach den Text (Ten's Multiple) an das Ende des Button-Texts anhängt, wann immer die Methode aufgerufen wird. Unser vollständiger Code sieht jetzt ungefähr so aus:

cs

index

copy
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
using System.Runtime.CompilerServices; namespace EventsIntro { public class CounterEvent { public event EventHandler? AtTensMultiple; public void CountCheck(int count) { EventHandler? handler = AtTensMultiple; if (handler != null) { if (count % 10 == 0) { handler(this, new EventArgs()); } } } } public partial class MainPage : ContentPage { int count = 0; CounterEvent counter = new CounterEvent(); public MainPage() { InitializeComponent(); CounterBtn.Clicked += OnCounterClicked; counter.AtTensMultiple += Reformat; } private void Reformat(object? sender, EventArgs e) { CounterBtn.Text += " " + "(Ten's Multiple)"; } private void OnCounterClicked(object? sender, EventArgs e) { count++; if (count == 1) CounterBtn.Text = $"Clicked {count} time"; else CounterBtn.Text = $"Clicked {count} times"; counter.CountCheck(count); } } }

Wenn wir das Programm jetzt ausführen und den Button 10 Mal klicken, erscheint der Text (Ten's Multiple) im Button-Text. Wenn Sie ihn 20 Mal drücken, passiert dasselbe erneut. Und so weiter.

Um nun Argumente an die Reformat-Methode zu übergeben, können wir eine neue Klasse namens CustomEventArgs erstellen, die von EventArgs abgeleitet ist, und in dieser Klasse einige öffentliche Eigenschaften haben, die die Parameter darstellen können:

cs

index

copy
123456789
public class CounterArgs : EventArgs { public string Text { get; } // Here 'Text' can act as a parameter or argument. public CounterArgs(string text) { this.Text = text; } }

Jetzt, da wir eine CustomEvenArgs-Klasse haben, müssen wir einige Änderungen an der CounterEvent-Klasse vornehmen:

cs

index

copy
12345678910111213141516171819
public class CounterEvent { public delegate void CounterEventHandler(object sender, CounterArgs e); public event CounterEventHandler? AtTensMultiple; public void CountCheck(int count) { CounterEventHandler? handler = AtTensMultiple; if (handler != null) { if (count % 10 == 0) { handler(this, new CounterArgs("(something random)")); } } } }

Im obigen Code erstellen wir zuerst eine neue Definition für den EventHandler und nennen ihn CustomEventHandler, wobei wir den Datentyp des zweiten Parameters auf CustomEventArgs setzen.

Zweitens übergeben wir new CounterArgs("something random") als zweites Argument beim Aufrufen des Event-Handlers. Dadurch können wir die Zeichenfolgendaten (something random) als Argument an die Refactor-Methode übergeben, auf die wir so zugreifen können:

cs

index

copy
12345
// Modified signature to support 'CounterArgs' instead of 'EventArgs' private void Reformat(object? sender, CounterArgs e) { CounterBtn.Text += " " + e.Text; }

Also, unser endgültiger Code sollte in etwa so aussehen:

cs

index

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
using System.Runtime.CompilerServices; namespace EventsIntro { public class CounterEvent { public delegate void CustomEventHandler(object? sender, CounterArgs e); public event CustomEventHandler? AtTensMultiple; public void CountCheck(int count) { CustomEventHandler? handler = AtTensMultiple; if (handler != null) { if (count % 10 == 0) { handler(this, new CounterArgs("(something random)")); } } } } public class CounterArgs : EventArgs { public string Text { get; } public CounterArgs(string text) { this.Text = text; } } public partial class MainPage : ContentPage { int count = 0; CounterEvent counter = new CounterEvent(); public MainPage() { InitializeComponent(); CounterBtn.Clicked += OnCounterClicked; counter.AtTensMultiple += Reformat; } private void Reformat(object? sender, CounterArgs e) { CounterBtn.Text += " " + e.Text; } private void OnCounterClicked(object? sender, EventArgs e) { count++; if (count == 1) CounterBtn.Text = $"Clicked {count} time"; else CounterBtn.Text = $"Clicked {count} times"; counter.CountCheck(count); } } }

Wenn Sie das obige Programm ausführen, wird der Text (something random) an das Ende des Button-Texts angehängt, wann immer der count ein Vielfaches von zehn ist. Dies zeigt an, dass die Daten erfolgreich in die Abonnentenmethoden übergeben werden.

Wichtige Punkte:

  • Die Publisher-Klasse enthält die Definition und eine Instanz des benutzerdefinierten Ereignishandler-Delegaten;
  • Die Definition des Ereignishandler-Delegaten kann übersprungen werden, wenn wir den EventHandler-Delegatentyp verwenden, um die Instanz zu erstellen;
  • Es gibt eine Methode in der Publisher-Klasse, die dafür verantwortlich ist, den Delegaten aufzurufen, wann immer es relevant ist;
  • Die Delegateninstanz sollte öffentlich sein, um sie für Abonnentenklassen zugänglich zu machen;
  • Wir können Argumente in Ereignishandlermethoden übergeben, indem wir unsere eigene Klasse erstellen, die von EventArgs abgeleitet ist und Eigenschaften hat, die die Daten oder Argumente darstellen, die wir übergeben möchten;

1. Welches Schlüsselwort verwenden wir, um einen normalen Delegaten in einen Ereignishandler zu konvertieren?

2. Von welcher Klasse müssen wir erben, wenn wir benutzerdefinierte Ereignismethodenargumente erstellen?

Welches Schlüsselwort verwenden wir, um einen normalen Delegaten in einen Ereignishandler zu konvertieren?

Welches Schlüsselwort verwenden wir, um einen normalen Delegaten in einen Ereignishandler zu konvertieren?

Wählen Sie die richtige Antwort aus

Von welcher Klasse müssen wir erben, wenn wir benutzerdefinierte Ereignismethodenargumente erstellen?

Von welcher Klasse müssen wir erben, wenn wir benutzerdefinierte Ereignismethodenargumente erstellen?

Wählen Sie die richtige Antwort aus

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 5
We're sorry to hear that something went wrong. What happened?
some-alt