Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Événements Personnalisés | GUI Interactif
C# Avancé Avec .NET
course content

Contenu du cours

C# Avancé Avec .NET

C# Avancé Avec .NET

1. Introduction au Développement de Bureau avec .NET
2. GUI Interactif
3. Threading
4. Génériques et Réflexion

book
Événements Personnalisés

Dans le chapitre précédent, nous avons appris à lier des méthodes aux gestionnaires d'événements, mais est-il possible de créer nos propres événements ? Oui, en fait, c'est assez simple à faire.

Un système d'événements se compose de deux parties : la classe Éditeur et la classe Abonné. Il y a toujours une seule classe Éditeur pour un événement, cependant, il peut y avoir plusieurs classes Abonné.

Une classe Éditeur contient le délégué du gestionnaire d'événements pour l'événement, et une méthode pour invoquer ce délégué chaque fois que cela est pertinent.

Une classe est appelée classe Abonné dans ce contexte si elle souscrit une méthode au gestionnaire d'événements de la classe Éditeur.

Le diagramme suivant montre le flux de processus d'un système d'événements :

Nous allons créer un système d'événements simple en partant du projet par défaut. À l'intérieur du fichier C#, nous créons d'abord une nouvelle classe appelée CounterEvent qui va représenter la classe Éditeur, et elle va avoir une instance EventHandler que nous créons en utilisant le type EventHandler déjà existant :

cs

index

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

Cette classe a également besoin d'une méthode pour invoquer le gestionnaire d'événements chaque fois que nécessaire. Nous pouvons créer un événement qui est déclenché chaque fois que la condition count % 10 == 0 est satisfaite, où count est le nombre de fois que l'utilisateur a cliqué sur le CounterBtn. Définissons d'abord la méthode d'invocation à l'intérieur de CounterEvent, nous l'appellerons CountCheck car elle vérifiera essentiellement la valeur de count chaque fois qu'elle est appelée et elle invoquera AtTensMultiple lorsque la condition est satisfaite.

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()); } } } }

Ici, l'argument this est passé pour représenter le sender et new EventArgs() représente une nouvelle instance d'une classe vide. Nous pouvons passer des données dans les méthodes qui se sont abonnées au gestionnaire d'événements, lorsque le gestionnaire d'événements est invoqué, en utilisant ce deuxième argument, cependant, comme nous passons EventArgs qui est une classe vide, aucune donnée n'est passée. Nous verrons comment passer des données de cette manière dans un instant.

Maintenant que la méthode d'invocation est définie, notre classe éditeur est à peu près complète. Nous devons faire deux choses de plus :

  1. Créer une instance de la classe éditeur ;
  2. Appeler la méthode d'invocation pour la rendre fonctionnelle ;

Donc, d'abord, je vais créer une instance à l'intérieur de la classe MainPage:

cs

index

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

Et maintenant, appelons cette méthode à l'intérieur de OnCounterClicked afin qu'elle effectue une vérification chaque fois que l'utilisateur clique sur le bouton.

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); }

Maintenant que notre événement est fonctionnel, nous sommes prêts à lier une méthode au gestionnaire d'événements. Je vais créer une nouvelle méthode appelée Reformat qui ajoute simplement le texte (Ten's Multiple) à la fin du texte du bouton chaque fois que la méthode est invoquée. Notre code complet ressemblera à ceci maintenant :

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); } } }

Donc maintenant, si nous exécutons le programme et cliquons sur le bouton 10 fois, le texte (Ten's Multiple) apparaîtra dans le texte du bouton. Si vous appuyez dessus 20 fois, la même chose se reproduira. Et ainsi de suite.

Maintenant, pour passer des arguments à la méthode Reformat, nous pouvons créer une nouvelle classe appelée CustomEventArgs dérivée de EventArgs, et nous pouvons avoir certaines propriétés publiques dans cette classe qui peuvent représenter les paramètres :

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; } }

Maintenant que nous avons une classe CustomEvenArgs, nous devons apporter quelques modifications à la classe CounterEvent :

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)")); } } } }

Dans le code ci-dessus, nous créons d'abord une nouvelle définition pour le EventHandler et l'appelons CustomEventHandler, où nous définissons le type de données du deuxième paramètre à CustomEventArgs.

Deuxièmement, nous passons new CounterArgs("something random") comme deuxième argument lors de l'appel du gestionnaire d'événements. Cela nous permet de passer la donnée de chaîne (something random) comme argument à la méthode Refactor, que nous pouvons accéder comme ceci :

cs

index

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

Donc, maintenant, notre code final devrait ressembler à ceci :

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); } } }

Si vous exécutez le programme ci-dessus, le texte (something random) sera ajouté à la fin du texte du bouton chaque fois que le count est un multiple de dix. Ce qui indique que les données sont correctement transmises aux méthodes abonnées.

Points Importants :

  • La Classe Émettrice contient la définition et une instance du délégué de gestionnaire d'événements personnalisé ;
  • On peut sauter la définition du Délégué de Gestionnaire d'Événements si nous utilisons le type de délégué EventHandler pour créer l'instance ;
  • Il y a une méthode dans la Classe Émettrice qui est responsable de l'invocation du délégué chaque fois que c'est pertinent ;
  • L'Instance du Délégué doit être publique pour la rendre accessible aux classes abonnées ;
  • Nous pouvons passer des arguments dans les Méthodes de Gestionnaire d'Événements en créant notre propre classe qui dérive de EventArgs et en ayant des propriétés qui représentent les données ou les arguments que nous voulons passer ;

1. Quel mot-clé utilisons-nous pour convertir un délégué normal en gestionnaire d'événements ?

2. De quelle classe devons-nous hériter lors de la création d'arguments de méthode d'événement personnalisés ?

Quel mot-clé utilisons-nous pour convertir un délégué normal en gestionnaire d'événements ?

Quel mot-clé utilisons-nous pour convertir un délégué normal en gestionnaire d'événements ?

Sélectionnez la réponse correcte

De quelle classe devons-nous hériter lors de la création d'arguments de méthode d'événement personnalisés ?

De quelle classe devons-nous hériter lors de la création d'arguments de méthode d'événement personnalisés ?

Sélectionnez la réponse correcte

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

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