2012-04-01 14 views
1

Ich habe einen Knopf. Auf Button.MouseRightButtonDown rufe ich Mouse.Capture (Schaltfläche) auf, weil ich feststellen möchte, ob jemand einen Rechtsklick außerhalb des Buttons freigibt.Kann ich ein MouseLeave-Ereignis erhalten, während Mouse.Capture() aktiv ist?

Ich habe auch ein Ereignis Button.MouseLeave registriert. Wenn jemand mit der rechten Maustaste die Maus aus der Schaltfläche zieht, möchte ich, dass dieses Ereignis ausgelöst wird.

Leider scheint Mouse.Capture irgendwie MouseLeave zu blockieren.

Kennt jemand einen Workaround, oder kann er vielleicht aufzeigen, wo ich falsch liege?

(By the way, wenn jemand neugierig ist, was ich das tue für siehe my other question.)

Antwort

4

Wenn Maus gefangen wird, können Sie Move verwenden und Hit-Tests, ob die Maus in Ihrem Element oder eine andere zu bestimmen.

protected override void OnMouseMove(MouseEventArgs e) 
{ 
    base.OnMouseMove(e); 

    if (this.IsMouseCaptured) 
    { 
     HitTestResult ht = VisualTreeHelper.HitTest(this, e.GetPosition(this)); 
     if (ht != null) 
     { 
      DependencyObject current = ht.VisualHit; 
      while (current != this && current != null) 
      { 
       current = VisualTreeHelper.GetParent(current); 
      } 

      if (current == this) 
      { 
       Debug.WriteLine("Inside"); 
       return; 
      } 
     } 

     Debug.WriteLine("Outside"); 
    } 
} 

Der folgende Code verwendet werden kann Baum zu Fuß zu vermeiden:

protected override void OnMouseMove(MouseEventArgs e) 
{ 
    base.OnMouseMove(e); 

    if (this.IsMouseCaptured) 
    { 
     bool isInside = false; 

     VisualTreeHelper.HitTest(
      this, 
      d => 
      { 
       if (d == this) 
       { 
        isInside = true; 
       } 

       return HitTestFilterBehavior.Stop; 
      }, 
      ht => HitTestResultBehavior.Stop, 
      new PointHitTestParameters(e.GetPosition(this))); 

     if (isInside) 
     { 
      Debug.WriteLine("Inside"); 
     } 
     else 
     { 
      Debug.WriteLine("Outside"); 
     } 
    } 
} 
+0

Das hat wunderbar funktioniert. Vielen Dank. –

0

Nach meiner Antwort auf Ihre Frage im Zusammenhang auf, wenn Sie CaptureMouse() von UIElement anstelle von Mouse.Capture verwenden (...) dann wirst du das richtige Verhalten sehen.

public class MyButton : Button 
{ 
    protected override void OnMouseRightButtonDown(MouseButtonEventArgs e) 
    { 
     base.OnMouseRightButtonDown(e); 
     CaptureMouse(); 
    } 

    protected override void OnMouseRightButtonUp(MouseButtonEventArgs e) 
    { 
     base.OnMouseRightButtonUp(e); 
     ReleaseMouseCapture(); 
    } 

    protected override void OnMouseEnter(MouseEventArgs e) 
    { 
     base.OnMouseEnter(e); 
     Debug.WriteLine("Mouse enter"); 
    } 

    protected override void OnMouseLeave(MouseEventArgs e) 
    { 
     base.OnMouseLeave(e); 
     Debug.WriteLine("Mouse leave"); 
    } 
} 
+0

In meinem vorhandenen Code, Ändern Mouse.Capture() zu CaptureMouse() anscheinend nicht jedes Verhalten zu ändern. –

+0

In meinem einfachen Test habe ich ein Fenster und eine benutzerdefinierte Schaltfläche (wie oben). Wenn ich mit der rechten Maustaste auf die Schaltfläche klicke und dann die Maustaste loslasse, bekomme ich eine Debug-Meldung "Maus verlassen". – Phil

+1

XP vs Win7 Unterschied? –