2011-11-09 30 views
2

我有一個選項卡控件,可以將選項卡項目拖出我的應用程序。
這個拖動將打開一個新的窗口,它將跟隨鼠標,直到我釋放鼠標左鍵。
此外,可以將選項卡項拖回到源選項卡控件中,並將其重新附加到其前父項或任何其他能夠理解拖動數據的控件。如何在執行拖放操作時將hitTest通過控件傳遞

private static void DragOutTabControl_PreviewQueryContinueDrag(object sender, QueryContinueDragEventArgs e) 
{ 
    e.Handled = true; 

    if (DragControlIsHit) 
    { 
     if (_previewWindow != null && _previewWindow.IsVisible) 
     { 
     _previewWindow.Clear(); 
     _previewWindow.Hide(); 
     } 
    } 
    else 
    { 
     if (_previewWindow == null) 
     { 
     _previewWindow = new PreviewWindow(); 
     _previewWindow.SetData(); 
     } 

     _previewWindow.Left = CursorPos.X - 15; 
     _previewWindow.Top = CursorPos.Y - 15; 
     _previewWindow.Show(); 
    } 
} 

我現在遇到的問題是,當預覽窗口跟在鼠標後面時,它直接位於光標下方。
通過這種方式,源選項卡控件的dragEnter和dragOver事件不會觸發,因爲窗口阻止了命中測試。
即使我在窗口中將IsHitTestVisible設置爲false,在拖動&拖放仍處於活動狀態時,命中測試將被阻止。
將IsEnabled設置爲false並將背景更改爲null不起任何作用。

public PreviewWindow() 
{ 
    Background = null; 
    IsEnabled = false; 
    IsHitTestVisible = false; 
} 

是否有任何可能將隱藏預覽窗口從任何命中測試或手動將命中測試傳遞到拖動窗口後面的任何控件?

編輯,我的問題的一些更多信息:
我不僅想要將標籤項拖出我的標籤控件,併爲他們打開新的窗口,而且我希望能夠拖動額外的標籤項目到現有的拖出窗口。
另外,應該可以將選項卡項目拖回到原始選項卡控件中。

除了唯一的問題,我無法隱藏拖動& drop-hittesting的預覽窗口,這一切都工作得很好。

回答

1

我有一個類似的問題有關DragDrop事件命中測試,並the answer我收到的是切換到使用的MouseEvents代替DragDrop事件。我做了開關,從不後悔,也沒有試過回到WPF的內置DragDrop事件。

作爲一種替代方案,如果您不想使用鼠標事件,將顯示您的窗口在Adorner層而不是UI層,並且只有在發生Drop事件時纔將其渲染爲新對象。

+0

首先,感謝您的回答。 它支持我自己對該主題的想法,但由於我必須能夠處理從其他來源的拖放,我不想使用普通的MouseEvent而不是DragDropEvents。 – lukas

+0

另外我給了裝飾者一個嘗試,但我不喜歡在釋放鼠標按鈕時創建窗口。 – lukas

2

Rachel的回答絕對正確,我會推薦給任何人使用正常的MouseEvent而不是DragDropEvents。
但因爲我有好幾個窗口在我捲入拖動應用程序,我不得不想出一個不同的解決方案:

private static void ProcessDraggedHitTest(
     Window window) 
    { 
     var CursorPos = GetCursorPos(); 
     var MousePosition = Mouse.GetPosition(window); 

     IDragTarget hitControl = null; 
     var hitTestResult = VisualTreeHelper.HitTest(window, new Point(CursorPos.X + MousePosition.X, CursorPos.Y + MousePosition.Y)); 
     if (hitTestResult != null) 
     { 
      var parent = hitTestResult.VisualHit as DependencyObject; 
      while (parent != null) 
      { 
       hitControl = parent as IDragTarget; 
       if (tileOutControl != null) 
        break; 
       else 
        parent = VisualTreeHelper.GetParent(parent); 
      } 

      if (hitControl != null) 
       DragOver(hitControl, _draggedItem); 
     } 
    } 

其中的dragover(hitControl,_draggedItem)是正常調用的函數時爲dragenter或DragOver事件觸發並且GetCursorPos()是Win32調用來獲取正確的鼠標位置。

現在您必須以正確的z順序爲所有窗口調用該函數,然後就完成了。

我希望我可以幫助解決我的問題,但是如果有人發現了一個更好的方法來做到這一點,我很有興趣聽到它。

相關問題