IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

empecher les doubles abonnements aux events


Sujet :

Windows Forms

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut empecher les doubles abonnements aux events
    Bonjour.

    J'aimerai savoir si il est possible d'empecher que l'on s'abonne 2 fois à un meme evenement?

    Revons un peu :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    monBouton.Click += superHandler.GrosseOreille();
    monBouton.Click += superHandler.GrosseOreille();
     
    Resultat :
    Message de SuperHandler : Abonnement etabli
    Message de SuperHandler : Abonnement inutile
    Bon ok, le code est totalement utopique, mais je suis face à la somme des 2 problemes suivants :
    1)monBouton peut etre l'instance de n'importe quelle classe, meme une sealed provenant d'une dll que je n'ai pas concu.
    2) les event sont uniquement left part, donc je ne peux pas le passer en parametre à GrosseOreille.

    Je crain vraiment que 2) soit la réponse à ma question, mais peut on toujours rever

    Merci d'avance pour vos réponses.

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Bon j'ai fini par trouver une solution, meme si j'ai l'impression d'avoir un peu réinventé la roue j'aurai du aller me coucher

    Je vous pond le code qui fonctionne tres bien.

    Les 2 classes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    using System;
    using System.Collections.Generic;
    using System.Reflection;
     
    namespace essaiEventDoubleAbonnement
    {
        internal class EHentry
        {
            internal object m_emmiter;
            internal String m_event;
            internal Delegate m_eventHandler;
     
            public EHentry(object emeteur, String evenement, Delegate eventhandler)
            {
                m_emmiter = emeteur;
                m_event = evenement;
                m_eventHandler = eventhandler;
            }
     
            public static bool operator ==(EHentry obj1, EHentry obj2)
            {
                    if (obj1.m_emmiter == obj2.m_emmiter
                        && String.Compare(obj1.m_event, obj2.m_event) == 0
                        && obj1.m_eventHandler == obj2.m_eventHandler)
                        return true;
                    else
                        return false;
            }
     
            public static bool operator !=(EHentry obj1, EHentry obj2)
            {
                return !(obj1 == obj2);
            }
     
            public override bool Equals(object obj)
            {
                return this == obj;
            }
     
        }
        class SingletonEventHandler
        {
            private List<EHentry> m_handlerRegistry;
     
            public SingletonEventHandler()
            {
                m_handlerRegistry = new List<EHentry>();
            }
     
            public bool Abonne(object emeteur, String evenement, Delegate eventHandler)
            {
                EventInfo eventInfo = Checkattribs(emeteur, evenement, eventHandler);
     
                EHentry newEntry = new EHentry(emeteur, evenement, eventHandler);
                if (m_handlerRegistry.Count > 0)
                {
                    foreach (EHentry item in m_handlerRegistry)
                    {
                        if (item == newEntry)
                            return false;
                    }
                }
     
                m_handlerRegistry.Add(newEntry);
                eventInfo.AddEventHandler(emeteur, eventHandler);
                return true;
     
            }
     
            public void Desabonne(object emeteur, String evenement, Delegate eventHandler)
            {
                EventInfo eventInfo = Checkattribs(emeteur, evenement, eventHandler);
                EHentry entryToRemove = new EHentry(emeteur, evenement, eventHandler);
                foreach (EHentry item in m_handlerRegistry)
                {
                    if (item == entryToRemove)
                    {
                        m_handlerRegistry.Remove(item);
                        break;
                    }
                } //OSEF si il ne le trouve pas ;)
                eventInfo.RemoveEventHandler(emeteur, eventHandler);
     
            }
     
            /// <summary>
            /// Que ce soit pour abonner ou desabonner, les memes choses sont à vérifier coté params passé à la fonction, alors je les ai regroupé dans une autre fonction.
            /// </summary>
            private EventInfo Checkattribs(object emeteur, String evenement, Delegate eventHandler)
            {
                if (emeteur == null)
                    throw new ArgumentNullException("emeteur");
                if (eventHandler == null)
                    throw new ArgumentNullException("eventHandler");
     
                Type typeEmeteur = emeteur.GetType();
                EventInfo eventInfo = typeEmeteur.GetEvent(evenement);
                if (eventInfo == null)
                    throw new ArgumentException(String.Format("la classe \"{0}\" ne contient pas d'evenement \"{1}\r\n", typeEmeteur, evenement));
                if (!(eventInfo.EventHandlerType.Equals(eventHandler.GetType())))
                    throw new ArgumentException(String.Format("votre délégé n'est pas du bon type pour l'evenement que vous avez indiqué\r\nType du evenHandler pour l'evenement : {0}\r\ntype de votre EventHandler : {1}", eventInfo.EventHandlerType, eventHandler.GetType()));
                return eventInfo;
            }
        }
    }
    Le ptit code de demo:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    using System;
     
    namespace essaiEventDoubleAbonnement
    {
        class Program
        {
            static void Main(string[] args)
            {
                Class1 obj = new Class1();
                SingletonEventHandler grandeOreil = new SingletonEventHandler();
                EventHandler callback1 = new EventHandler(Callback);
                EventHandler callback2 = new EventHandler(Callback2);
     
                Console.WriteLine("Premiere injection de callback retourne : {0}", grandeOreil.Abonne(obj,"GoStarted",callback1));
                Console.WriteLine("Premiere injection de callback2 retourne : {0}", grandeOreil.Abonne(obj, "GoStarted", callback2));
                Console.WriteLine("Deuxieme injection de callback2 retourne : {0}\r\n", grandeOreil.Abonne(obj, "GoStarted", callback1));
                Console.WriteLine("Ce qui nous donne à l'appel de GO :\r\n");
                obj.Go();
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("On desabonne Callback1");
                grandeOreil.Desabonne(obj, "GoStarted", callback1);
                Console.WriteLine("Ce qui nous donne à l'appel de GO :\r\n");
                obj.Go();
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("Juste pour le plaisir on va désabonner une callback(3) malgres qu'on ne soit pas passé par grande oreille ;)\r\n");
                EventHandler callback3 = new EventHandler(Callback3);
                obj.GoStarted += callback3;
                Console.WriteLine("petit go apres avoir court circuité grandeoreille : ");
                obj.Go();
                Console.WriteLine("\r\ndésabonne callback3, puis ptit go pour terminer : ");
                grandeOreil.Desabonne(obj, "GoStarted", callback3);
                obj.Go();
                Console.WriteLine("\r\nOk cool ! bon pour finir, on va lui donner ce qu'il ne faut pas !");
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("quand on ne donne pas le bon nom d'evenement:\r\n");
                try
                {
                    grandeOreil.Abonne(obj,"EventFantomme",callback3);
                }
                catch(Exception e)
                {
                    Console.WriteLine(String.Format("ERREUR : {0}",e.Message));
                }
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("quand l'emeteur est null:\r\n");
                try
                {
                    grandeOreil.Abonne(null,"GoStarted",callback3);
                }
                catch(Exception e)
                {
                    Console.WriteLine(String.Format("ERREUR : {0}",e.Message));
                }
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("quand le eventHandler est null:\r\n");
                try
                {
                    EventHandler badHandler = null;
                    grandeOreil.Abonne(null, "GoStarted", badHandler);
                }
                catch (Exception e)
                {
                    Console.WriteLine(String.Format("ERREUR : {0}", e.Message));
                }
                Console.WriteLine("\r\nPresse Entrée pour la suite\r\n");
                Console.Read();
                Console.WriteLine("enfin quand le type du eventHandler n'est pas le bon !\r\n");
                try
                {
                    ConsoleCancelEventHandler handlerDeMauvaisType = new ConsoleCancelEventHandler(CallBackBidon);
                    grandeOreil.Abonne(obj, "GoStarted", handlerDeMauvaisType);
                }
                catch (Exception e)
                {
                    Console.WriteLine(String.Format("ERREUR : {0}", e.Message));
                }
                Console.WriteLine("\r\nPresse Entrée pour QUITTER\r\n");
                Console.Read();
     
     
            }
     
            public static void Callback(object sender, EventArgs e)
            {
                Console.WriteLine("Callback appellée");
            }
     
            public static void Callback2(object sender, EventArgs e)
            {
                Console.WriteLine("Callback2 appellée");
            }
     
            public static void Callback3(object sender, EventArgs e)
            {
                Console.WriteLine("Callback3 appellée");
            }
     
            public static void CallBackBidon(object blabla, ConsoleCancelEventArgs e)
            {
            }
        }
     
    public class Class1
        {
            public event EventHandler GoStarted;
     
            public Delegate[] Combien()
            {
                return GoStarted.GetInvocationList();
            }
            public void Go()
            {
                if (GoStarted != null)
                    GoStarted(this, new EventArgs());
            }
        }
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 9
    Dernier message: 11/01/2012, 09h37
  2. Réponses: 1
    Dernier message: 14/10/2009, 10h13
  3. [VBA-E] Effacer les doubles dans 1 colonne grace à une macro
    Par Stef.proxi dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 05/08/2004, 15h44
  4. empecher les doublons
    Par florent dans le forum Requêtes
    Réponses: 4
    Dernier message: 11/06/2004, 15h59
  5. Empecher les erreurs du débogeurs
    Par remixtech dans le forum EDI
    Réponses: 9
    Dernier message: 04/06/2003, 13h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo