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 :

Suppression dynamique d'événements sur un contrôle (avec delegate)


Sujet :

Windows Forms

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 20
    Points
    20
    Par défaut Suppression dynamique d'événements sur un contrôle (avec delegate)
    Bonjour,

    Suite à une création dynamique d'un événements sur un contrôle (en passant par un delegate), je souhaiterai pouvoir le supprimer dynamiquement.
    Création de l'événement:
    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
     
            private void InitialiseEvents()
            {
                // Suite au click, modifier le curseur
                this.m_image.MouseDown += delegate
                {
                    this.m_image.Visible = false;
                    Bitmap b = new Bitmap(GetImagePath());
                    IntPtr s = b.GetHicon();
                    Cursor c = new Cursor(s);
                    this.m_image.Parent.Parent.Cursor = c;
                };
            }
            private void DisableEvents()
            {
                 ?????????
            }
    Est-ce possible ? En accédant à la collection d'EventHandler liés au contrôle (si ça existe) ?
    Merci

  2. #2
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Je crois pas qu'il soit possible de désabonner une méthode anonyme.

    => Solution : que la méthode ne soit plus anonyme, ce qui sera pas difficile ici vu que la méthode en question n'utilise pas de variable de la méthode dans laquelle elle a été définie.

    Par ailleurs, je connais pas le contexte de ce bout de code, mais il me parait un brin bourrin d'aller rechercher sur le disque le curseur à chaque MouseDown... tu devrais stocker le curseur dans une variable de ta classe, par exemple.
    ಠ_ಠ

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 20
    Points
    20
    Par défaut
    Donc ça n'est pas possible
    Je voulais éviter de stocker les délégués anonymes en variable membres (du coup, elles ne seront plus anonymes ^^)

    Effectivement, l'exemple fourni est un peu hard mais c'était juste un projet test pour les délégués

    Merci.

  4. #4
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    De toutes façon, tu n'as pas vraiment besoin de désabonner. Il te suffit d'ajouter au début de ta méthode abonnée un "if (!activated) return;", où activated est une variable membre de ta classe, qu'il te suffit de modifier pour activer / désactiver.
    ಠ_ಠ

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 20
    Points
    20
    Par défaut
    Bonne idée mais le pointeur de fonction ne sera pas détruit par le garbage collector

    N'empêche que je suis surpris qu'il n'y ai pas moyen de retrouver tous ces délégués via un accesseur à partir du contrôle

  6. #6
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Citation Envoyé par Arno2xF Voir le message
    Bonne idée mais le pointeur de fonction ne sera pas détruit par le garbage collector
    Loin de moi l'idée de jouer au tatillon, mais ce que tu dis est faux à plusieurs niveaux
    Déjà, qu'un pointeur (ou plutôt une référence) soit détruit ou pas, on s'en fiche, puisque n'étant qu'une adresse, ça ne prend pas de place.

    Ensuite, la méthode anonyme est transformée par le compilo en méthode d'instance de ta classe (puisqu'elle ne capture aucune variable locale de la méthode où elle est déclarée, sinon le compilo aurait dû créer un objet, lui coller les variables capturées, et faire de la méthode anonyme une méthode de cet objet).
    Et donc, quand un objet A s'abonne à un objet B, ça ne crée pas une référence de A vers B (qu'en l'occurence tu as déjà, je suppose, puisque m_image est un membre de ta form ?), mais de B vers A. Il faut effectivement faire attention à désabonner des méthodes quand l'abonné a une durée de vie plus courte que l'émetteur, puisque l'émetteur garde une référence vers tous ses abonnés, et empêche donc le garbage collector de les collecter.

    Donc là, de toutes façons, vu que la durée de vie de m_image est inférieure à celle de ta form, pas besoin de te désabonner. Et ce, pour des raisons de perf en tous cas, tu peux vouloir te désabonner pour que le code ne s'exécute plus, mais comme je te disais précédemment un bon gros booléen est plus simple dans ce cas.

    Y'a peut être moyen de choper la collection de méthodes abonnées, mais perso j'en ai jamais eu besoin, et je pense partager ma situation avec 99.9% des participants à ce forum. En tous cas, clairement, vu le besoin que tu exprimes, t'en as pas besoin
    ಠ_ಠ

  7. #7
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Y'a peut être moyen de choper la collection de méthodes abonnées
    Oui, je crois que j'ai encorele bout de code quelque part (stocké en commentaire dans une bibli).
    J'essaierai de le retrouver demain et de le poster.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  8. #8
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    RemoveEventHandlers(button1,"Click") ;
    ...
    internal void RemoveEventHandlers(Control TheControl,string EventName)
    {
      System.Reflection.FieldInfo f1 = typeof(Control).GetField("Event"+EventName,
           System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
      object obj = f1.GetValue(TheControl); 
      System.Reflection.PropertyInfo pi = TheControl.GetType().GetProperty("Events",
           System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);             
      EventHandlerList list = (EventHandlerList)pi.GetValue(TheControl, null);
      list.RemoveHandler(obj, list[obj]);
    }
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  9. #9
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut liste des eventhandlers du controles,delegates
    bonjour
    elle est disponible pour les classes controls dans Control.Events

    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
     
     
    // The class SampleControl defines two event properties, MouseUp and MouseDown.
    class SampleControl: Component {
       // :
       // Define other control methods and properties.
       // :
     
       // Define the delegate collection.
       protected EventHandlerList listEventDelegates = new EventHandlerList();
     
       // Define a unique key for each event.
       static readonly object mouseDownEventKey = new object();
       static readonly object mouseUpEventKey = new object();
     
       // Define the MouseDown event property.
       public event MouseEventHandler MouseDown {  
          // Add the input delegate to the collection.
          add { listEventDelegates.AddHandler(mouseDownEventKey, value); }
          // Remove the input delegate from the collection.
          remove { listEventDelegates.RemoveHandler(mouseDownEventKey, value); }
       }
     
       // Define the MouseUp event property.
       public event MouseEventHandler MouseUp {
          // Add the input delegate to the collection.
          add { listEventDelegates.AddHandler(mouseUpEventKey, value); }
          // Remove the input delegate from the collection.
          remove { listEventDelegates.RemoveHandler(mouseUpEventKey, value); }
       }
    }
    bon code...............

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 18
    Points : 20
    Points
    20
    Par défaut
    Parfait ! Merci à tous

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/12/2014, 13h16
  2. Réponses: 2
    Dernier message: 03/12/2014, 09h34
  3. Réponses: 13
    Dernier message: 30/05/2012, 10h42
  4. Création dynamique de contrôles avec événements différents
    Par SphereDuNeant dans le forum Windows Forms
    Réponses: 1
    Dernier message: 26/10/2009, 21h28
  5. Dessin sur les contrôles avec VB6
    Par rxjmo dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 20/12/2007, 15h23

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