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 :

ToolTipText non fonctionnel


Sujet :

Windows Forms

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut ToolTipText non fonctionnel
    Salut
    -----

    J'ai un souci avec un contrôle personnalisé au niveau du tooltiptext. Celui-ci ne fonctionne pas.

    Mon contrôle présente la particularité d'avoir une pictureBox à fond transparent qui est superposée à l'intégralité du contrôle. Un clic sur le contrôle est donc, en interne, un clic sur le pictureBox (par exemple).

    J'ai pensé que c'était un problème d'évènements de souris détectés par le picturebox plutôt que par le contrôle, et donc j'ai redirigé tous les évènements souris du pictureBox vers le contrôle lui-même, comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      maPictureBox.MouseEnter += delegate(object s, EventArgs e) { this.OnMouseEnter(e); };
    Mais ça ne fonctionne pas.

    Quelqu'un sait-il comment faire pour que les tooltiptextes fonctionnent si le contrôle est "masqué" de cette façon?

    Le toolTip sur mes autres contrôles, non recouverts d'une pictureBox, fonctionne parfaitement.

    Merci,
    Claude

  2. #2
    Membre actif
    Homme Profil pro
    Chef de Projet
    Inscrit en
    Décembre 2012
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Chef de Projet
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Décembre 2012
    Messages : 113
    Points : 260
    Points
    260
    Par défaut
    Bonsoir,

    Je ne sais pas répondre à ta question initiale, mais est-il possible de changer de stratégie ?

    1) mettre ton tooltip sur la picture box
    2) l'objectif de la picture box est sans doute d'afficher une image par dessus ton contrôle. Peut être qu'au lieu d'utiliser un picturebox pour afficher ton image, tu peux redéfinir la méthode OnPaint ?

  3. #3
    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
    bonjour ClaudeBg

    Tu pourrais "tagge" le tooltip et faire en sorte d'utiliser un seul delegate(vu que ton picbox recouvre entierement le custcontrol) ou tu setteras le tooltip sur ton custcontrol...et le tooltip ne verras que du feu......
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    maPictureBox.MouseEnter += delegate(object s, EventArgs e)
     { code suit....};
    voici le code suggere:
    code .cs du custcontrol "tagge" :
    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
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace WinCustControl
    {
        public partial class CustControlTag : Control
        {
            private PictureBox pic;
            private ToolTip MytoolTip = null;
            public CustControlTag()
            {
                InitializeComponent();
               //add picturebox
                pic = new PictureBox();
                pic.BackColor = Color.Violet;
                pic.Dock = DockStyle.Fill;
                this.Controls.Add(pic);
                pic.MouseEnter += new EventHandler(pic_MouseEnter);
            }
            void pic_MouseEnter(object sender, EventArgs e)
            {
                MytoolTip  = this.Tag as ToolTip;
                if (MytoolTip != null)
                {
                    MytoolTip.SetToolTip(pic, "My Control");
                }
     
            }
            protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);
            }
        }
    }
    form utilisateur:
    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
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace WinCustControl
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }
     
            private void Form2_Load(object sender, EventArgs e)
            {
                // Create the ToolTip and associate with the Form container.
               ToolTip  toolTipTagged = new ToolTip();
     
                // Set up the delays for the ToolTip.
                toolTipTagged.AutoPopDelay = 5000;
                toolTipTagged.InitialDelay = 1000;
                toolTipTagged.ReshowDelay = 500;
                // Force the ToolTip text to be displayed whether or not the form is active.
                toolTipTagged.ShowAlways = true;
     
                // Set up the ToolTip text for the Button and Checkbox.
                toolTipTagged.SetToolTip(this.custControlTag1, "My Control");
               //memorise le tooltip dans prop tag du custcontrol
                this.custControlTag1.Tag = toolTipTagged;
            }
        }
    }
    bon code...............

  4. #4
    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
    Le toolTip sur mes autres contrôles, non recouverts d'une pictureBox, fonctionne parfaitement.
    Il se peut que le problème n'ait rien à voir avec la PictureBox transparente. Même avec des contrôles "normaux", les toolTip ne fonctionnent pas à 100%.
    On peut améliorer significativement les choses en mettant plusieurs instances de ToolTip pour chaque form, sans malheureusement que ce palliatif résolve tous les problèmes d'absence d'affichage.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Tout d'abord, merci pour vos réponses.
    Dans l'ordre :

    1) mettre ton tooltip sur la picture box
    Ce n'est pas moi qui met le tooltip. Moi, je construis les contrôles, qui seront utilisés par moi mais aussi par d'autres. La pictureBox est private, le designer met le tooltip sur le contrôle lui-même, pas sur un de ses éléments internes.

    l'objectif de la picture box est sans doute d'afficher une image par dessus ton contrôle. Peut être qu'au lieu d'utiliser un picturebox pour afficher ton image, tu peux redéfinir la méthode OnPaint ?
    Je surcharge déjà OnPaint. Le contrôle est composé d'une partie "fixe" qu'on redessine peu souvent et d'une partie "mobile". La pictureBox me permet de modifier la partie mobile sans devoir redessiner tout le contrôle. J'ai utilisé cette façon de procéder pour alléger le travail de redessin de tout le contrôle si ce n'était pas nécessaire.

    Mais c'est clair que si je mets tous mes éléments dans OnPaint je n'ai plus ce problème. Du reste, mes autres contrôles n'ont pas de picturebox et le tooltip fonctionne parfaitement.

    Tu pourrais "tagge" le tooltip et faire en sorte d'utiliser un seul delegate(vu que ton picbox recouvre entierement le custcontrol) ou tu setteras le tooltip sur ton custcontrol...et le tooltip ne verras que du feu......
    Le problème c'est que pour faire ça il faut agir au niveau de la form qui utilise le tooltip. Or, je n'y ai pas accès puisque j'ignore comment vont être utilisés les contrôles.

    Il se peut que le problème n'ait rien à voir avec la PictureBox transparente. Même avec des contrôles "normaux", les toolTip ne fonctionnent pas à 100%.
    On peut améliorer significativement les choses en mettant plusieurs instances de ToolTip pour chaque form, sans malheureusement que ce palliatif résolve tous les problèmes d'absence d'affichage.
    Le projet est une librairie de contrôles qui en contient un certain nombre.
    Tous fonctionnent sauf celui qui a une picturebox qui le couvre.
    Les probabilités sont très fortes que le problème vienne de là.

    Pour résumer: ce dont j'ai besoin, c'est d'une façon de procéder qui soit du code présent uniquement dans le contrôle en question, l'utilisateur utilisant le contrôle doit pouvoir ajouter "bêtement" le contrôle sur sa form et se servir du tooltip de la façon habituelle.

    Ceci, sachant que simplement "dérouter" les évènements souris reçus par la picturebox vers le contrôle lui-même est une méthode qui ne fonctionne pas. J'ignore pourquoi.

    Merci,
    Claude

  6. #6
    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
    rebonjour

    Le code donne est toujours valable mais un minimum d' information doit etre donne pour situer le contexte du probleme sinon ca fait des pages de "parlotes".....................
    Dans ton cas il suffit de faire simplement une prop (publique browsable si tu veux que l'user le customise) ou une prop private(cas contraire):
    code .cs du custcontrol
    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
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace WinCustControl
    {
        public partial class CustControl : Control
        {
            private PictureBox pic;
            private ToolTip m_MytoolTip = new ToolTip();
            private string txtTooltip ="My CustControl";
            public CustControl()
            {
                InitializeComponent();
     
                //set tooltip to CustControl
                m_MytoolTip.SetToolTip(this, txtTooltip);
     
                //set  PictureBox
                pic = new PictureBox();
                pic.BackColor = Color.Violet;
                pic.Dock = DockStyle.Fill;
                this.Controls.Add(pic);
                this.BackColor = Color.Turquoise;
                pic.MouseEnter += new EventHandler(pic_MouseEnter);
     
            }
            void pic_MouseEnter(object sender, EventArgs e)
            {
                if (MytoolTip != null)
                {
                    //get the current  text 
                    string s = MytoolTip.GetToolTip(this);
                    MytoolTip.SetToolTip(pic, s);
                }
     
            }
     
     
            protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);
            }
     
            //property tooltip
            [Browsable(true)]
            public ToolTip  MytoolTip 
            {
                get { return m_MytoolTip; } 
                set
                {
                    m_MytoolTip=value ;
                } 
            }
     
        }
    }
    form user:
    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
     
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace WinCustControl
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
                this.custControl1.MytoolTip.SetToolTip(custControl1, "ClaudeBg");
            }
     
            private void Form2_Load(object sender, EventArgs e)
            {
     
            }
        }
    }
    bonne soiree.........

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Le code donne est toujours valable mais un minimum d' information doit etre donne pour situer le contexte du probleme sinon ca fait des pages de "parlotes"
    La librairie de contrôles se trouve en téléchargement gratuit sur le "Topic des composants gratuits dotNET " (au dessus de la page du forum winform).
    Le contrôle concerné est le BgKnobSingle.
    Il y a une fenêtre de démo fournie, avec sources, il suffit d'affecter un texte tooltip à un KnobSingle pour vérifier que ça ne fonctionne pas, alors que ça fonctionne avec les autres contrôles.

    Les sources sont fournis.

    Dans ton cas il suffit de faire simplement une prop (publique browsable si tu veux que l'user le customise) ou une prop private(cas contraire): code .cs du custcontrol
    J'ai bien compris ce que tu m'expliquais, MAIS ta méthode implique d'utiliser une procédure spéciale pour le tooltip. Je dois dire à l'utilisateur: "si tu utilises ce contrôle et que tu veux un tooltip, tu dois utiliser une propriété tooltip parce que le tooltip normal ne fonctionne pas". Avoue que ce n'est pas vraiment élégant.

    De plus, les modifications "à la volée" du tooltip ne se répercuteront pas sur le toolTip de ce contrôle, il faudra aussi faire une "exception" en codant en dur le paramétrage du nouveau tooltip.

    Moi, ce dont j'ai besoin, c'est tout simplement que mon contrôle fonctionne comme n'importe quel autre contrôle :

    1) J'ai un toolTip sur la form
    2) Je mets mon contrôle sur la form
    3) J'entre une valeur dans le champs "toolTip" standard.

    Et, si, en cours de route, je change le fonctionnement du tooltip, genre l'utilisateur via un menu le rend invisible, change la durée, etc, que ce contrôle se comporte comme les autres et réagisse aux modifications des paramètres du tooltip de la fenêtre.

    Bref, pas une sorte de "second tooltip" à initialiser séparément du toolTip principal.

    Pour faire ça il me faudrait:

    1) Soit savoir quand un tooltip référence mon contrôle, avec possibilité de récupérer le toolTIp en question (mais je vois mal comment faire car comment savoir qu'un tooltip s'est abonné à MouseMove par exemple)

    2) Soit répercuter tout évènement de la souris (enter, move, etc) reçu sur la PictureBox vers le contrôle lui-même, comme ça lorsque la souris entre dans le picturebox, elle entre aussi dans le contrôle. Mais j'ai testé et ça ne fonctionne pas. J'en déduis que le mécanisme en oeuvre sur le toolTip n'utilise pas les abonnements à ces évènements classique et opère différemment.

    Bref, comment, en conservant le fonctionnement normal du toolTip, sans propriété "spéciale" à imposer à l'utilisateur, faire que mon contrôle réagisse comme les autres, même s'il dispose d'une picturebox interne en avant-plan? Du reste, cette picturebox fait partie du contrôle, je comprends mal que le tooltip ne fonctionne pas, le contrôle reste un contrôle peu importe de quoi il est constitué (du moins je le pensais).

    S'il n'y a aucune méthode élégante, je peux tenter lors du MouseEnter de vérifier si un éventuel ToolTip de la fenêtre référence mon contrôle, et alors forcer le tooltip sur le picturebox. Je testerai si personne n'a une meilleure idée.

    Merci
    A+
    Claude

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    A priori le tooltip sur un usercontrol ne s'affiche que sur le background du usercontrol (là ou il n'y a rien) et non pas sur les controls internes (qui utiliseront leur propre tooltip).

    http://social.msdn.microsoft.com/For...-809001ec040f/

    L'idée est de propager la propriété tooltip du usercontrol sur les controls internes.

    Par contre j'ai lu la problématique en diagonale, donc j'ai une chance sur 2 d'être complétement à côté de la plaque par rapport à ta question :-)

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Par contre j'ai lu la problématique en diagonale, donc j'ai une chance sur 2 d'être complétement à côté de la plaque par rapport à ta question :-)
    Non, tu n'es pas du tout "à côté de la plaque" ce que tu m'expliques et le lien que tu donnes parlent explicitement de mon problème. Merci

    Je note donc que le toolTip a un défaut de fonctionnement lorsque le contrôle est composé de sous-contrôles internes.

    La solution consistant à résoudre le problème est donc:

    - Soit comme déjà expliqué par les autres intervenants: modifier la form et la façon de gérer le tooltip

    - Soit comme le lien l'explique: en modifiant carrément le fonctionnement du toolTip par une extension

    Comme, de mon côté, je n'ai accès ni à la form de l'utilisateur, ni à son toolTip, vu que je propose uniquement le contrôle, il ne semble pas y avoir de solution reconnue et fonctionnelle jusqu'à présent.

    Je vais voir si je trouve une astuce. Si oui, je l'indiquerai ici, si non, je laisse le sujet ouvert au cas où un internaute aurait une solution.

    Dans l'attente, merci déjà à tous pour vos explications.

    A+
    Claude

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Bon, j'y suis arrivé.

    Je dois m'absenter, mais je poste ma solution tout à l'heure pour ceux que ça intéresse ou qui seraient concernés par ce type de problème (usercontrols composites, contrôles utilisateurs avec contrôles intégrés etc)

    Merci à tous pour vos réponses

    A+
    Claude

  11. #11
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Je note donc que le toolTip a un défaut de fonctionnement lorsque le contrôle est composé de sous-contrôles internes.
    Je ne sais pas si on peut vraiement parler d'un défaut de fonctionnement. Dans certains cas, il est peut être intéressant d'avoir un tooltip différent en fonction que l'on soit sous un bouton ou une textbox du usercontrol.

    A savoir qu'il existe plusieurs façon d'implémenter un "custom control" sous winforms (la principal différence étant la class mère de premier niveau). Le usercontrol est le plus restrictif mais le plus rapide (simple) à mettre en place.

    C'est pourquoi je l'utilise personnellement plutôt uniquement dans le cadre d'un projet afin d'éviter la répétion sur un groupe de contrôle ayant un comportement commun à plusieurs endroits du logiciel (parfois aussi pour représenté une vue graphique d'un objet, ce qui n'empechera pas que le binding s'effectue entre les propriétés de l'objet et les souscontrôle).

    Je recommande la lecture suivante pour en savoir plus.

    http://www.akadia.com/services/dotne...tom%20Controls

    Peut être que dans ton cas, utiliser le concept du Owner-drawn controls serait plus approprié (partir de la class control et non pas usercontrol)


    P.S. J'attends de lire ta solution avec impatience :-)

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Je ne sais pas si on peut vraiement parler d'un défaut de fonctionnement. Dans certains cas, il est peut être intéressant d'avoir un tooltip différent en fonction que l'on soit sous un bouton ou une textbox du usercontrol.
    À partir du moment où en mode design on ne sait plus utiliser de toolTip sur un contrôle contenant d'autres contrôles, je pense pour ma part qu'il s'agit d'un défaut de fonctionnement. Mais bon...

    Le usercontrol est le plus restrictif mais le plus rapide (simple) à mettre en place.
    Tout dépend de ce qu'on cherche à faire. Pour un contrôle combinant plusieurs contrôles enfants, c'est pratique (une zone de saisie + un bouton par exemple). Pour un contrôle offrant des possibilités spécifiques, et n'est pas très efficace. Si on veut modifier le comportement d'un contrôle de base non plus.

    Bref, la façon de procéder dépend de ce qu'on cherche à faire. Je pense qu'on sera d'accord sur ce point

    Peut être que dans ton cas, utiliser le concept du Owner-drawn controls serait plus approprié (partir de la class control et non pas usercontrol)
    Justement, ce contrôle dérive de Control, ce n'est pas un usercontrol.

    P.S. J'attends de lire ta solution avec impatience :-)
    Bon, voilà mon raisonnement:

    - Je me suis dit qu'en mode design l'utilisateur allait placer le contrôle sur la form disposant (ou non) d'un toolTip, et que, si tooltip il y a il écrit son texte dans la propriété "ToolTip" du contrôle.

    - En mode "ajout dynamique de contrôles" soit il procède de la même façon, soit il modifie le contenu du texte tooltip dynamiquement. Dans ce dernier cas, ajouter une méthode spécifique genre "ChangeToolTip" ne pose aucun problème.

    Bref, dans le cas de figure "standard", on a la situation suivante:

    1) Le toolTip est déclaré de façon "private" dans la form dans laquelle le contrôle se trouve
    2) Le designer affecte un toolTip au contrôle avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monToolTip.SetToolTip(monControl);
    Ce qui ne fonctionne pas sur les contrôles intégrés à "monControl", d'où le problème.

    Le but est donc de faire en sorte que

    monToolTip.SetToolTip(monControl)

    agisse en interne comme

    monToolTip.SetToolTip(monControlInterne);

    Voici ma solution:

    1) Je m'abonne à l'évènement MouseEnter de mon contrôle "fils". Dans mon cas, c'est une pictureBox appelée _pbMobil. Je m'abonne dès la création du contrôle principal. Tout ce qui suit se déroule dans la méthode de l'évènement MouseEnter:

    2) Je récupère la fenêtre dans laquelle mon contrôle est placé, et donc la fenêtre qui référence en "private" le toolTip

    3) Par réflexion, je récupère tous les champs privés de l'instance de la fenêtre que je viens de récupérer

    4) Je cherche si dans ces champs privés j'ai un champs de type "ToolTip". Si oui, j'ai trouvé mon toolTip

    5) Je demande au toolTip de me renvoyer le texte associé au toolTip de mon contrôle. S'il me renvoie un texte c'est que l'utilisateur a placé un toolTip sur mon contrôle (donc sur "this" à l'intérieur de ma méthode)

    6) J'ai le toolTip, j'ai le texte, il ne reste qu'à associer le toolTip au contrôle interne (donc à ma pictureBox).

    À ce stade, j'ai le toolTip de la fenêtre qui a initialisé un texte à la fois sur le contrôle lui-même et sur le ou les contrôles fils. Le toolTip fonctionne quel que soit l'endroit où on place la souris à l'intérieur du contrôle (sur un contrôle enfant ou sur le fond du contrôle lui-même.

    7) Je me désabonner de MouseEnter, ce qui m'évite de rechercher et d'affecter le tooltip à chaque fois que j'entre avec la souris dans le contrôle. Si on ne désabonne pas, on peut éventuellement checker si le texte du toolTip a été modifié, c'est au choix.

    En gérant tout dans MouseEnter plutôt que dans le constructeur, on est certain que le toolTip existe déjà car placé en mode design alors qu'on est en mode run.

    Le code final donne ceci :

    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
            void _pbMobil_MouseEnter(object sender, EventArgs e)
            {
                // Récupère la form contenant le contrôle
                var form = this.FindForm();
     
                // récupérer informations sur tous les éléments privés de l'instance de la form
                var fieldsInfos = form.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
     
                // Récuperer le champs privé correspondant à un ToolTip faisant partie de la fenêtre du contrôle
                var fieldInfo =
                    (from fi in fieldsInfos
                     where fi.FieldType == typeof(ToolTip)
                     select fi).FirstOrDefault();
     
                // Si trouvé un Tooltip référencé dans la fenêtre
                if (fieldInfo != null)
                {
                    // récupérer ce toolTip
                    var toolTip = (ToolTip)fieldInfo.GetValue(form);
                    // Récupérer son texte
                    var text = toolTip.GetToolTip(this);
                    // Affecter à la pictureBox le même toolTip que celui affecté au contrôle
                    if (text != string.Empty)
                        toolTip.SetToolTip(_pbMobil,text);
                }
                // Se désabonner à l'évènement MouseEnter
                _pbMobil.MouseEnter -= _pbMobil_MouseEnter;
            }
    En fait, c'est tout simple

    A+
    Claude

  13. #13
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Rien d'autre à dire que la patience pour ta réponse était amplement justifiée.

    Bravo pour cette solution

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Bravo pour cette solution
    Merci

    En fait, lorsque j'ai voulu réellement utiliser les toolTip sur mon contrôle, j'ai vu qu'il restait un dernier souci. En effet, ça fonctionne tant qu'on ne clique pas sur le contrôle interne. Une fois qu'on l'a fait, le toolTip cesse de fonctionner, comme s'il n'était pas "réarmé".

    J'ai donc fait différents essais, et j'ai constaté que même si on intercepte toutes les actions de la souris, un clic sur un contrôle interne désactive le tooltip.

    J'ai donc commencé par couper le désabonnement à MouseEnter, mais alors le toolTip fonctionnait de façon curieuse (mal positionné, action sans délai etc), comme si on avait plusieurs fois le toolTip pour un même contrôle (il doit y avoir un bug dans ToolTip).

    Je me suis aperçu qu'affecter deux fois un texte à un toolTip de cette nature provoquait un fonctionnement erroné. Par contre, en passant par l'envoi d'un texte "string.empty", celui-ci annulait le ToolTip et il suffisait de renvoyer le bon texte ensuite.

    J'ai donc modifié le code ci-dessus, selon le principe suivant:

    1) Au premier passage dans MouseEnter, je localise le toolTip. Je ne le fais donc qu'une seule fois.

    2) À chaque passage dans MouseEnter, si le toolTip a été détecté au premier passage, j'annule le texte du tooltip puis je le renvoie.

    Ainsi, le toolTip est réarmé correctement et fonctionne sans soucis, tout en ne consommant pas du temps CPU inutile sur MouseEnter.

    Voici le code final:

    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
            void _pbMobil_MouseEnter(object sender, EventArgs e)
            {
                if (!_toolTipInitalized)                                // si toolTip pas encore cherché
                {
                    var form = this.FindForm();                         // Récupère la form contenant le contrôle
     
                    // récupérer informations sur tous les éléments privés de l'instance de la form
                    var fieldsInfos = form.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
     
                    // Récuperer le champs privé correspondant à un ToolTip faisant partie de la fenêtre du contrôle
                    var fieldInfo =
                        (from fi in fieldsInfos
                        where fi.FieldType == typeof(ToolTip)
                        select fi).FirstOrDefault();
     
                    if (fieldInfo != null)                              // Si trouvé un Tooltip référencé dans la fenêtre
                        _toolTip = (ToolTip)fieldInfo.GetValue(form);   // le récupérer, conserver une référence dessus
     
                    _toolTipInitalized = true;                          // ToolTip détecté (s'il existe)
     
                    if (_toolTip == null)                               // si pas de toolTip
                    {
                        _pbMobil.MouseEnter -= _pbMobil_MouseEnter;     // se désabonner définitivement
                        return;                                         // inutile de poursuivre
                    }
                }
     
                var text = _toolTip.GetToolTip(this);                   // récupérer texte du toolTip
                if (text != string.Empty)                               // si on a un texte associé
                {
                    _toolTip.SetToolTip(_pbMobil, string.Empty);        // l'annuler (obligatoire)
                    _toolTip.SetToolTip(_pbMobil, text);                // le réarmer
                }
            }
    Comme ça, ça semble fonctionner sans problème.

    L'avantage annexe de cette méthode, c'est que si on change dynamiquement le texte du toolTip en cours de fonctionnement, il est maintenant mis à jour automatiquement.

    Mes contrôles publics seront mis à jour pour demain avec la nouvelle version

    A+
    Claude

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

Discussions similaires

  1. Flash Disque non fonctionnel
    Par stanley dans le forum Composants
    Réponses: 2
    Dernier message: 18/07/2006, 12h18
  2. Code non fonctionnel sous IE
    Par Nip dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 07/06/2006, 14h59
  3. timage non fonctionnel !!
    Par micky13 dans le forum Delphi
    Réponses: 5
    Dernier message: 13/05/2006, 07h21
  4. Update non fonctionnel
    Par kissmytoe dans le forum Access
    Réponses: 7
    Dernier message: 07/03/2006, 18h37
  5. [REPORTS] Order BY non fonctionnel
    Par sdiack dans le forum Reports
    Réponses: 2
    Dernier message: 10/02/2006, 18h10

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