2012-10-09 34 views
4

我遇到一些問題DragDrop.DoDragDrop與左鍵單擊事件很好地協同工作。WPF手柄拖放以及左鍵單擊

我的控件有幾個鏈接,可以拖動或左鍵單擊來訪問。

我目前訂閱預覽鼠標移動事件,這是我按下鼠標左鍵啓動拖放事件的地方。

在另一個回調中,我處理鼠標左鍵向下和向上事件以檢查點擊。無論如何檢查DragDrop是否真的有一個拖放事件發生?

回答

13

this link drag drop in wpf explained end to end和向下滾動一點點輸入的部分「檢測將&滴」在這裏插入包住博客就不復存在了

代碼...

從[http://msdn2.microsoft.com/en-us/library/aa289508(vs.71).aspx]這裏是在事件發生的順序典型的拖放操作:

通過調用源控件的DoDragDrop方法來啓動拖動。

DoDragDrop方法有兩個參數: 數據,指定數據傳遞allowedEffects,指定哪個操作(複製和/或移動)被允許

被自動創建一個新的數據對象的對象。 這反過來引發了GiveFeedback事件。在大多數情況下,您不必擔心GiveFeedback事件,但是如果您想在拖動過程中顯示自定義鼠標指針,則可以在此添加代碼。

其AllowDrop屬性設置爲True的任何控件都是潛在的放置目標。 AllowDrop屬性可以在設計時在屬性窗口中設置,或者在Form_Load事件中以編程方式設置。

當鼠標經過每個控件時,會引發該控件的DragEnter事件。 GetDataPresent方法用於確保數據的格式適合於目標控件,Effect屬性用於顯示相應的鼠標指針。

如果用戶通過有效放置目標釋放鼠標按鈕,則會引發DragDrop事件。 DragDrop事件處理程序中的代碼從DataObject對象中提取數據並將其顯示在目標控件中。

檢測將&降

在之前的DoDragDrop被調用時,我們必須檢測源鼠標拖拽操作......鼠標拖動通常是的MouseLeftButtonDown +一個的MouseMove(MouseLeftButton上升之前)。

所以,我們的拖放&放置源控件需要訂閱這兩個事件:

void Window1_Loaded(object sender, RoutedEventArgs e) 
{ 
    this.DragSource.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DragSource_PreviewMouseLeftButtonDown); 
    this.DragSource.PreviewMouseMove += new MouseEventHandler(DragSource_PreviewMouseMove); 
} 

從開始當用戶不小心拖動虛假拖動&拖放操作阻止,你可以使用

SystemParameters.MinimumHorizo​​ntalDragDistance和SystemParameters.MinimumVerticalDragDistance

一種方式做,這是對的MouseLeftButtonDown,記錄起始位置的OnMouseMove檢查鼠標已經遠遠不夠..

void DragSource_PreviewMouseMove(object sender, MouseEventArgs e) 
{ 
    if (e.LeftButton == MouseButtonState.Pressed && !IsDragging) 
    { 
     Point position = e.GetPosition(null); 

     if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance || 
       Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance) 
     { 
      StartDrag(e); 

     } 
    } 
} 

void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    _startPoint = e.GetPosition(null); 
} 

它是一種將..現在該怎麼辦?

該數據!拖動時需要找出鼠標下的內容。 我會省略簡單的方法,並假設誰觸發MouseMove是我想拖..所以看看MouseEventArgs.OriginalSource .. [或者你可以做一些2D HitTesting使用VisualTreeHelper ..在這寫的第3部分up會嘗試引導你通過命中測試列表框 - 這是我遇到的另一種常見場景 - 。

一旦你有拖動的對象,你需要打包你發送到一個數據對象,描述你傳遞的數據。 DataObject是將通用數據(用可擴展格式標識)推入拖放的包裝。只要源和目標都瞭解格式,就會設置。因此,DataObject有一些有趣的方法:

SetData(類型格式,對象數據)///格式是你傳遞的那天的格式(例如Formats.Text,Formats.Image等..)你可以傳遞任何自定義類型。

GetDataPresent(類型格式)///是放置目標會用什麼來查詢和提取數據。如果它是一個類型,它可以處理,它會調用的GetData(),並處理它..

這裏沒有太多有趣的東西..在示例中,我只是將我的數據硬編碼爲字符串類型......這可以更容易地粘貼到外部容器中(例如Word,您可以使用它來測試此部分的寫作)。我必須強調,拖動&下探應該是關於數據... 拖動&拖放操作過程中提供視覺反饋..

之前我們所說的DoDragDrop(),我們有一些「選擇」,使周圍的我們希望提供的反饋和d的「範圍」d。

我們是否希望在執行拖動操作時顯示自定義光標?如果我們想要一個遊標,它應該是什麼?

我們想拖多遠?在應用程序內還是跨Windows應用程序?

簡單的場景:沒有定義光標,我們希望它在整個應用程序拖到:

如果你不想看上光標做,你做!您可以撥打的DoDragDrop直接...

private void StartDrag(MouseEventArgs e) 
{ 
    IsDragging = true; 
    DataObject data = new DataObject(System.Windows.DataFormats.Text.ToString(), "abcd"); 
    DragDropEffects de = DragDrop.DoDragDrop(this.DragSource, data, DragDropEffects.Move); 
    IsDragging = false; 
} 

注:此代碼使您能夠將整個過程&下降,它使用默認的操作系統反饋(例如+用於複製)..

+0

完美的作品,非常感謝! – bgura

+1

5年後,我得到了一個沒有解釋的downvote,愚蠢的系統,讓它。 –

0

有拖曳Over/Enter/Leave附加事件 您可以將方法訂閱到拖動的UIElement上的這些(或一個)事件,並查看拖動是否發生。