2010-06-14 2 views
2

Lorsque j'appelle CaptureMouse() en réponse à un MouseDown à partir du bouton central de la souris, il capture, puis relâche la souris.Quelle est la particularité de la capture de la souris et du bouton central de la souris dans WPF?

Huh?

J'ai essayé d'utiliser des événements de prévisualisation, le réglage Handled = true ne fait pas de différence. Est-ce que je ne comprends pas la capture de souris dans WPF?

Voici un exemple de code minimal qui reproduit le problème.

// TestListBox.cs 

using System.Diagnostics; 
using System.Windows.Controls; 

namespace Local 
{ 
    public class TestListBox : ListBox 
    { 
     public TestListBox() 
     { 
      MouseDown += (_, e) => 
      { 
       Debug.WriteLine("+MouseDown"); 
       Debug.WriteLine(" Capture: " + CaptureMouse()); 
       Debug.WriteLine("-MouseDown"); 
      }; 

      GotMouseCapture += (_, e) => Debug.WriteLine("GotMouseCapture"); 
      LostMouseCapture += (_, e) => Debug.WriteLine("LostMouseCapture"); 
     } 
    } 
} 

Génération d'un défaut application WPF qui a cela pour la fenêtre principale utilisera la classe de test:

<Window x:Class="Local.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:Local" 
     Title="MainWindow" Height="350" Width="525"> 
    <local:TestListBox> 
     <ListBoxItem>1</ListBoxItem> 
     <ListBoxItem>2</ListBoxItem> 
     <ListBoxItem>3</ListBoxItem> 
     <ListBoxItem>4</ListBoxItem> 
    </local:TestListBox> 
</Window> 

Après avoir cliqué sur le bouton du milieu vers le bas, je reçois cette sortie:

+MouseDown 
GotMouseCapture 
LostMouseCapture 
Capture: True 
-MouseDown 

J'appelle donc CaptureMouse, qui à son tour attrape et libère la capture, mais retourne vrai que la capture a été acquise avec succès.

Que se passe-t-il ici? Est-il possible que ce soit quelque chose avec mon pilote de souris Logitech faire quelque chose de goofy, en essayant d'initier «ultrascroll» ou quelque chose?

Répondre

1

Cela peut être diagnostiqué en définissant votre débogueur pour interrompre la méthode UIElement.ReleaseMouseCapture() et en regardant la pile d'appels. Si vous faites cela, vous trouverez que c'est l'OnMouseMove de ListBox qui cause le problème.

Donc, tout ce que vous devez faire pour passer outre est OnMouseMove et non appeler la classe de base si le bouton est en bas:

public class TestListBox : ListBox 
{ 
    protected override void OnMouseMove(MouseEventArgs e) 
    { 
    if(Mouse.MiddleButton!=MouseButtonState.Pressed) 
     base.OnMouseMove(e); 
    } 
} 
+0

Merci! Je regardais la pile et il était si profond que je n'ai pas remarqué le OnMouseMove. Et bien sûr, en regardant ListBox.OnMouseMove dans Reflector, je vois qu'il libère la capture de la souris si le bouton gauche n'est pas enfoncé. – scobi

0

J'ai trouvé quelqu'un d'autre avait rencontré le même problème et l'a réduit à un problème spécifique avec ListBox.

http://social.msdn.microsoft.com/Forums/en/wpf/thread/5487c21a-1527-4a4f-bdf5-62de921d2ae0?prof=required

Si je passe à une toile, alors il fonctionne comme je l'attends. Donc, le ListBox fait quelque chose avec la capture. Gérer les choses via Previews avec Handled = true et même en remplaçant OnGotMouseCapture etc. sans appeler la base ne résout pas le problème.

Questions connexes