2010-08-02 2 views
5

Je répète cette question en raison de l'impossibilité de résoudre le problème (original here). Dans le TreeView, ListBox, ou il semble de mes recherches google n'importe quoi avec un ScrollBar, le ScrollBar n'est pas considéré comme une partie du contrôle.L'événement MouseLeave se déclenche lors du déplacement du contrôle ScrollBar

J'ai un TreeView que je mets dans un contrôle personnalisé, et c'est Dock Fill. Donc là, il agit comme un TreeView personnalisé qui a toute notre logique pour le gérer en un seul endroit.

Dans certaines parties de notre programme, nous le faisons glisser en fonction d'un événement MouseEnter et le réinsérons dans un événement MouseLeave, mais nous utilisons actuellement TreeView d'une bibliothèque tierce pour laquelle j'ai été chargé de le remplacer.

J'ai donc tout déplacé sur Windows TreeView, mais je n'arrive pas à trouver un moyen fiable de capturer le MouseLeave -seulement- s'il laisse toute la TreeView, barre de défilement incluse.

J'ai vu une solution hackish de l'envelopper dans un panneau avec plusieurs pixels et de capturer le MouseLeave du panneau, mais je ne crois pas que c'est ce que Microsoft nous avait prévu de faire dans cette situation.

En bref:

La barre de défilement ne se déclenche pas MouseEnter ou MouseLeave pour le contrôle, et qui rend l'utilisation MouseEnter/MouseLeave pour faire glisser le contrôle inutilisable car l'utilisateur ne peut pas utiliser l'ascenseur.

Quelle est la meilleure façon de gérer cette situation?

Dans la question précédente, on m'a conseillé d'utiliser Spy ++ et de tenter de se connecter à WndProc() pour gérer MouseEnter/MouseLeave pour ScrollBar.

Cela n'a toutefois pas fonctionné car les messages Spy ++ montraient qu'ils ne tiraient pas dans le WndProc() au niveau du formulaire ou du niveau de contrôle. C'est comme si .NET ne pouvait pas voir le ScrollBar. Utiliser WndProc() semble également irréaliste pour une requête aussi simple, existe-t-il un autre moyen de le faire, ou si WndProc() est le seul moyen, est-ce que quelqu'un a réussi à le faire et m'a montré comment?

Répondre

4

Il n'y a pas de solution propre pour cela. Votre tour de panneau ne fonctionne pas non plus, il sera complètement manqué lorsque l'utilisateur bouge la souris rapidement.

Pount. Une fois que vous obtenez MouseEnter, démarrez un minuteur 200 msec. Dans l'événement Tick, vérifiez si la souris survole toujours l'arborescence. Par exemple:

private void treeView1_MouseEnter(object sender, EventArgs e) { 
     timer1.Enabled = true; 
     treeView1.Width = 220; 
    } 

    private void timer1_Tick(object sender, EventArgs e) { 
     Point pos = treeView1.PointToClient(Cursor.Position); 
     if (!treeView1.DisplayRectangle.Contains(pos)) { 
      timer1.Enabled = false; 
      treeView1.Width = 50; 
     } 
    } 

L'événement Application.Idle fonctionne trop btw, juste un petit peu plus maladroit. Merci pour l'Astuce avait le même problème, j'ai modifié l'événement timer_Tick pour inclure la barre de défilement en ajoutant 20 à la largeur

+0

Cela a fonctionné parfaitement, merci! –

2

private void tmrListPos_Tick(object sender, EventArgs e) 
    { 
     Point posLB = clbPlants.PointToClient(Cursor.Position); 
     Rectangle rectPlants = clbPlants.DisplayRectangle; 
     rectPlants.Width = rectPlants.Size.Width + 20; 
     if (!rectPlants.Contains(posLB)) 
     { 
      tmrListPos.Enabled = false; 
      clbPlants.Size = clbPlants.MinimumSize; 
     } 
    } 
Questions connexes