Evénement MouseEnter et Tooltip

L'utilisation combinée de l'évènement MouseEnter et d'une ToolTip sur un même composant est soumis à problème.

Prenons un composant graphique d'une grande taille. La souris vient dessus, déclenche instantanément MouseEnter puis au bout d'un certain délai, la ToolTip s'affiche. Ensuite, la ToolTip étant apparue dessus le composant, il est possible de déplacer la souris dessus. Et c'est à ce moment que le problème arrive. Si la souris arrive à aller dessus, l'évènement MouseEnter est déclenchée en boucle.

Le seul moyen que j'ai trouvé est d'installer une tempo entre deux appels de l’événement MouseEnter et si elle est inférieure à une certaine valeur (faire quelques tests mais 50ms semble suffisant), forcer la disparition de la ToolTip.

Donc : Créer un composant graphique dérivé de ToolTip dans lequel, à chaque événement Popup, sa référence est stockée. C'est nécessaire car il n'est pas possible de connaître le ToolTip depuis un composant.

public class ToolTipPerso : ToolTip
{
    static public ToolTip LastToolTipShown { get; private set; }
 
    private void ToolTipPopup(object sender, PopupEventArgs e)
    {
        LastToolTipShown = this;
    }
 
    public ToolTipPerso(Control ctrl, string texte)
    {
        AutoPopDelay = 5000;
        InitialDelay = 300;
        ReshowDelay = 300;
        ShowAlways = false;
        UseAnimation = false;
        UseFading = false;
        SetToolTip(ctrl, texte);
        Popup += new PopupEventHandler(ToolTipPopup);
    }
}

Affecter la ToolTip de la façon suivante :

new ToolTipPerso(ctrl, texte);

Puis, dans l'événement MouseEnter : gérer le temps entre deux appels :

// Stocke le temps écoulé entre deux appels
private Stopwatch timeWatch = new Stopwatch();
 
public void MouseEnter(object sender, EventArgs e)
{
    if (timeWatch.IsRunning)
    {
        timeWatch.Stop();
        if (timeWatch.ElapsedMilliseconds < 50)
        {
            // On masque la ToolTip pour éviter l'appel en boucle de MouseEnter
            ToolTipPerso.LastToolTipShown.Hide((IWin32Window)sender);
        }
    }
 
    timeWatch.Reset();
    timeWatch.Start();
 
    ....
}