2017-07-19 93 views
0

我想在容器中拖動控件的同時獲取鼠標位置,這樣我就可以將自動滾動邏輯添加到容器中。但是,拖動時MouseMove根本不會觸發,DragOver只有在拖動內部控件時纔會觸發。wpf如何在容器中拖動控件時獲取鼠標位置?

測試例如

可拖動的小發明:

public class Gizmo : TextBlock 
    { 
     public Gizmo() 
     { 
      this.AllowDrop = true; 
      this.Background = Brushes.Gray; 
      this.Margin = new System.Windows.Thickness(6); 
     } 

     public Gizmo(string content) : this() 
     { 
      this.Text = content; 
     } 

     private bool isDragging; 
     private Point lastPressedLocation; 

     protected override void OnPreviewMouseMove(System.Windows.Input.MouseEventArgs e) 
     { 
      if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed) 
      { 
       if (!this.isDragging) 
       { 
        Point newLocation = e.GetPosition(this); 
        Vector offset = this.lastPressedLocation - newLocation; 
        if (offset.LengthSquared > 36) 
        { 
         this.lastPressedLocation = newLocation; 
         this.isDragging = true; 

         System.Windows.DragDrop.DoDragDrop(this, DateTime.Now, DragDropEffects.Move); 
        } 
        else 
        { 
         this.isDragging = false; 
        } 
       } 
      } 
     } 

     private bool canDrop; 

     protected override void OnPreviewDragEnter(DragEventArgs e) 
     { 
      Console.WriteLine("drag enter inside"); 
      if (this.Text == "gizmo 1") 
      { 
       e.Effects = DragDropEffects.Move; 
       this.canDrop = true; 
      } 
      else 
      { 
       e.Effects = DragDropEffects.None; 
       this.canDrop = false; 
      } 
      e.Handled = true; 
      base.OnPreviewDragEnter(e); 
     } 

     protected override void OnPreviewDragOver(DragEventArgs e) 
     { 
      Console.WriteLine("drag over inside"); 
      if (this.canDrop) 
      { 
       e.Effects = DragDropEffects.Move; 
      } 
      else 
      { 
       e.Effects = DragDropEffects.None; 
       e.Handled = true; 
      } 
      base.OnPreviewDragOver(e); 
     } 
    } 

容器:

public class Container : WrapPanel 
    { 
     protected override void OnInitialized(EventArgs e) 
     { 
      for (int i = 1; i <= 16; i++) 
       this.Children.Add(new Gizmo(string.Format("gizmo {0}", i))); 

      base.OnInitialized(e); 
     } 

     protected override void OnPreviewDragEnter(System.Windows.DragEventArgs e) 
     { 
      Console.WriteLine("drag enter outside"); 
      base.OnPreviewDragEnter(e); 
     } 

     protected override void OnPreviewDragOver(System.Windows.DragEventArgs e) 
     { 
      //I want to get mouse postion here, but this will be called only when dragging over gizmo inside 
      Console.WriteLine("drag over outside"); 
      base.OnPreviewDragOver(e); 
     } 
    } 

running result and question

或者它只是不可能?

回答

0

代碼中的最後一個函數應該可以工作。或者(因爲在你之前不應該有其他處理事件的元素),所以可以使用OnDragOver方法而不是Preview

protected override void OnDragOver(DragEventArgs e) 
{ 
    Point position = e.GetPosition(this); 
} 

如果它不起作用,那通常意味着您的控件的特定區域不是可見的。確保IsHitTestVisibletrue(必須是,否則子元素也不會工作),並且您控制的Background不是null。如果你不想要背景,並且仍然能夠看到可見的擊中測試,請使用Transparent作爲背景。