13. Evénements

Le traitement des événements est essentiellement un processus par lequel un objet peut notifier d'autres objets qu'un événement s'est produit. Ce processus est largement encapsulé par les délégués multiples qui incorporent cette capacité.

13.1. Définir un délégué pour un événement

L'environnement d'exécution .NET fournit différents délégués de gestion d'événements, mais vous pouvez écrire les vôtres.
Code Résultat Remarques
using System;

namespace Exemples
{
    public delegate void MoveEventHandler(object source, MoveEventArgs e);
    public class MoveEventArgs : EventArgs
    {
        public int newPosition;
        public bool cancel;
        public MoveEventArgs(int newPosition)
        {
            this.newPosition = newPosition;
        }
    }
    class DefinirDelegueEvenement
    {
        static void Main(string[] args)
        {
            Console.ReadKey();
        }
    }
}
 
par convention, le premier paramètre du délégué indique la source de l'événement, tandis que le second paramètre dérive de System.EventArgs et contient les données à propose de l'événement.

13.2. Stocker des données pour un événement avec EventArgs

Dans l'exemple précédent, on voit que la classe EventArgs peut être dérivée pour inclure des informations pertinentes pour un événement particulier.

13.3. Déclarer et déclencher un événement

Une classe ou une structure peut déclarer un événement en appliquant le modificateur d'événement (event) à un champ de délégué.
Code Résultat Remarques
using System;

namespace Exemples
{
    public delegate void MoveEventHandler(object source, MoveEventArgs e);
    public class MoveEventArgs : EventArgs
    {
        public int newPosition;
        public bool cancel;
        public MoveEventArgs(int newPosition)
        {
            this.newPosition = newPosition;
        }
    }
    public class Slider
    {
        int position;
        public event MoveEventHandler Move;
        public int Position
        {
            get
            {
                return position;
            }
            set
            {
                if (position != value) // si la position a changé
                {
                    if (Move != null) // si la liste d'invocation n'est pas vide
                    {
                        MoveEventArgs args = new MoveEventArgs(value);
                        Move(this, args); // événement déclencheur
                        if (args.cancel)
                        {
                            return; // annulation...
                        }
                        else
                        {
                            position = value; // OK, on modifie la valeur
                        }
                    }
                }
            }
        } 
    }
    class DeclarerDeclencherEvenement
    {
        static void Main(string[] args)
        {
            Console.ReadKey();
        }
    }
}
 
Dans cet exemple, la classe Slider a une propriété Position qui déclenche un événement Move lorsque sa position change. Le mot clé event favorise l'encapsulation en s'assurant que seules les opérations += et -= peuvent être effectuées sur le délégué. Les autres classes peuvent agir sur l'événement, mais seul le Slider peut invoquer le délégué (déclencher l'événement) ou nettoyer la liste d'invocation du délégué.

13.4. Agir sur un événement avec un gestionnaire d'événement

Code Résultat Remarques
using System;

namespace Exemples
{
    public delegate void MoveEventHandler(object source, MoveEventArgs e);
    public class MoveEventArgs : EventArgs
    {
        public int newPosition;
        public bool cancel;
        public MoveEventArgs(int newPosition)
        {
            this.newPosition = newPosition;
        }
    }
    public class Slider
    {
        int position;
        public event MoveEventHandler Move;
        public int Position
        {
            get
            {
                return position;
            }
            set
            {
                if (position != value) // si la position a changé
                {
                    if (Move != null) // si la liste d'invocation n'est pas vide
                    {
                        MoveEventArgs args = new MoveEventArgs(value);
                        Move(this, args); // événement déclencheur
                        if (args.cancel)
                        {
                            return; // annulation...
                        }
                        else
                        {
                            position = value; // OK, on modifie la valeur
                        }
                    }
                }
            }
        }
    }
    class GestionnaireEvenement
    {
        static void Main(string[] args)
        {           
            Slider slider = new Slider();
            slider.Move += new MoveEventHandler(slider_Move);
            slider.Position = 33;
            slider.Position = 133;
            Console.ReadKey();
        }
        static void slider_Move(object source, MoveEventArgs e)
        {
            if (e.newPosition < 100)
            {
                Console.WriteLine(e.newPosition + " : OK");
            }
            else
            {
                e.cancel = true;
                Console.WriteLine(e.newPosition + " : ne peut pas aller là !");
            }
        }
    }
}
33 : OK
133 : ne peut pas aller là !
Dans cet exemple, nous voulons que notre programme agisse en fonction du changement de la Position du Slider. Ceci est réalisé en créant un délégué MoveEventHandler qui englobe notre méthode de gestion d'événement (la méthode slider_Move). Ce délégué est ajouté à la liste existante des événements Move de MoveEventHandler (qui est vide à l'origine). Le changement de Position du Slider déclenche l'événement Move, qui invoque notre méthode slider_Move.
Généralement, la classe Slider est étendue pour que l'événement Move soit déclenché même si sa Position est changée par un mouvement de souris, une pression sur une touche, etc.


Pour plus d'information :
EventArgs, classe : http://msdn.microsoft.com/fr-fr/library/system.eventargs.aspx