2012-04-01 1 views
1

У меня есть кнопка. В Button.MouseRightButtonDown я вызываю Mouse.Capture (кнопка), потому что хочу обнаружить, что кто-то выпускает щелчок правой кнопкой мыши за пределами кнопки.Могу ли я получить событие MouseLeave, пока активен Mouse.Capture()?

У меня также есть событие Button.MouseLeave. Если кто-то щелкнет правой кнопкой мыши, перетащите мышь с кнопки, я хочу, чтобы это событие запустилось.

К сожалению, похоже, что Mouse.Capture каким-то образом блокирует MouseLeave.

Кто-нибудь знает обходное решение или может указать, где я иду не так?

(Кстати, если кто-то любопытно, что я делаю это для см my other question.)

ответ

4

Когда мышь захвачена, вы можете использовать MouseMove и hit-testing, чтобы определить, находится ли мышь внутри вашего элемента или другого.

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"); 
    } 
} 

Следующий код может быть использован, чтобы избежать дерева ходьбы:

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

Это сработало красиво. Спасибо. –

0

Исходя из моего ответа на ваш связанный с этим вопрос, если вы используете CaptureMouse() из UIElement вместо Mouse.Capture (...), то вы увидите правильное поведение.

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

В моем существующем коде, изменения Mouse.Capture() к CaptureMouse() не приведет к изменению любого поведения. –

+0

В моем простом испытании у меня есть окно и пользовательская кнопка (как указано выше). Если я нажму правой кнопкой мыши на кнопке, а затем отпустите мышь от кнопки, я получу отладочное сообщение «Отключение мыши». – Phil

+1

XP vs Win7 разница? –