共用方式為


拖放概觀

更新:2011 年 4 月

本主題提供 Windows Presentation Foundation (WPF) 應用程式中之拖放支援的概觀。 拖放通常是指一種資料轉送方法,牽涉到使用滑鼠 (或其他指標裝置) 選取一個或多個物件,然後將這些物件拖曳到user interface (UI) 中某個所要的置放目標,再放置這些物件。

這個主題包含下列章節。

  • WPF 中的拖放支援
  • 資料轉送
  • 拖放事件
  • 實作拖放功能
  • 拖放範例
  • 相關主題

WPF 中的拖放支援

拖放作業通常會牽涉到兩個單位:被拖曳物件原本所在的拖曳來源,以及接收被放置物件的置放目標。 拖曳來源與置放目標可以是同一個應用程式或不同應用程式中的 UI 項目。

可以透過拖放來操作的物件類型和數目完全沒有限制。 例如,檔案、資料夾和內容選取範圍是可透過拖放作業來操作的一些較常見的物件。

拖放作業期間執行的特定動作是應用程式所特有的,而且常由內容決定。 例如,從一個資料夾將檔案選取範圍拖曳到相同儲存裝置的另一個資料夾,此動作預設會移動檔案。然而從Universal Naming Convention (UNC) 共用拖曳檔案到本機資料夾,依預設會複製檔案。

WPF 所提供的拖放機能具有高度的彈性與可自訂性設計,可支援各式各樣的拖放情節。 拖放作業支援在單一應用程式內或在不同應用程式之間操作物件。 此外,也完全支援在 WPF 應用程式與其他 Windows 應用程式之間進行拖放。

在 WPF 中,任何 UIElementContentElement 都可以參與拖放。 拖放作業所需的事件和方法是定義在 DragDrop 類別中。 UIElementContentElement 類別包含 DragDrop 附加事件的別名,所以當繼承 UIElementContentElement 做為基底項目時,這些事件會出現在類別成員清單中。 附加至這些事件的事件處理常式是附加至基礎 DragDrop 附加事件,因此會接收同一個事件資料執行個體。 如需詳細資訊,請參閱 UIElement.Drop 事件。

安全性注意事項安全性注意事項

OLE 拖放作業在網際網路區域中無法運作。

資料轉送

拖放是其中一種較普遍的資料轉送方式。 資料轉送包括拖放和複製貼上作業。 拖放作業與透過系統剪貼簿在不同物件或應用程式之間轉送資料的複製貼上或剪下貼上作業類似。 這兩種作業都需要:

  • 一個提供資料的來源物件。

  • 一個暫時儲存所轉送資料的地方。

  • 一個接收資料的目標物件。

在複製貼上作業中,是使用系統剪貼簿來暫時儲存所轉送的資料,而在拖放作業中,則是使用 DataObject 來儲存該資料。 在概念上,資料物件包含一個或多個由 Object (包含實際資料) 和對應的資料格式識別項組成的配對。

拖放作業是由拖曳來源啟始,方法是呼叫靜態 DragDrop.DoDragDrop 方法並將轉送的資料傳遞給該方法。 DoDragDrop 方法會視需要將資料自動包裝在 DataObject 中。 若要更確實控制資料格式,您可以將資料包裝在 DataObject 中,再將資料傳遞給 DoDragDrop 方法。 置放目標負責從 DataObject 擷取資料。 如需使用資料物件的詳細資訊,請參閱資料與資料物件

拖放作業的來源和目標都是 UI 項目,但是實際轉送的資料通常並沒有視覺表示。 您可以撰寫程式碼來提供所拖曳資料的視覺表示,例如在 Windows 檔案總管中拖曳檔案時, 預設對使用者顯示的回應方式是變更游標來表示拖放作業將在資料上達到的效果,例如將會移動或複製資料。

拖放效果

拖放作業在所轉送的資料上可能會有不同效果。 例如,您可以複製資料或移動資料。 WPF 定義了 DragDropEffects 列舉,讓您用來指定拖放作業的效果。 在拖曳來源中,您可以在 DoDragDrop 方法中指定來源所允許的效果。 在置放目標中,您可以在 DragEventArgs 類別的 Effects 屬性中指定目標想要的效果。 當置放目標在 DragOver 事件中指定想要的效果時,該資訊會在 GiveFeedback 事件中傳回至拖曳來源。 拖曳來源會使用此資訊來通知使用者,指出置放目標想要在資料上達到的效果。 放置資料時,置放目標會在 Drop 事件中指定實際效果。 該資訊會當做 DoDragDrop 方法的傳回值,傳回至拖曳來源。 如果置放目標傳回的效果不在拖曳來源的 allowedEffects 清單中,則會取消拖放作業,而不會發生任何資料轉送。

切記,在 WPF 中,DragDropEffects 值只是用來在拖曳來源和置放目標之間,扮演溝通拖放作業效果的角色。 拖放作業的實際效果要靠您在應用程式中撰寫適當的程式碼。

例如,置放目標可能指定將資料放置在它上面的效果是移動資料。 不過,若要移動資枓,需要將資料加入至目標項目,同時從來源項目中移除該資料。 來源項目可能指出允許移動資料,但如果您未提供程式碼從來源項目中移除資料,則最後結果會是複製資料,而非移動資料。

拖放事件

拖放作業支援事件驅動模式。 拖曳來源和置放目標都使用標準事件集來處理拖放作業。 下表摘要列出標準的拖放事件。 這些是 DragDrop 類別上的附加事件。 如需附加事件的詳細資訊,請參閱附加事件概觀

拖曳來源事件

事件

摘要

[ E:System.Windows.DragDrop.GiveFeedback ]

拖放作業期間會持續發生這個事件,讓放置來源提供回應資訊給使用者。 這項回應的呈現方式通常是變更滑鼠指標的外觀,指出置放目標所允許的效果。 這是反昇事件。

[ E:System.Windows.DragDrop.QueryContinueDrag ]

當鍵盤或滑鼠按鈕狀態於拖放作業期間內變更時會發生這個事件,這個事件可讓置放來源根據按鍵/按鈕狀態取消拖放作業。 這是反昇事件。

[ E:System.Windows.DragDrop.PreviewGiveFeedback ]

GiveFeedback 的通道版本。

[ E:System.Windows.DragDrop.PreviewQueryContinueDrag ]

QueryContinueDrag 的通道版本。

置放目標事件

事件

摘要

[ E:System.Windows.DragDrop.DragEnter ]

當物件被拖曳入置放目標界限內時會發生這個事件。 這是反昇事件。

[ E:System.Windows.DragDrop.DragLeave ]

此事件在物件被拖曳出置放目標界限時發生。 這是反昇事件。

[ E:System.Windows.DragDrop.DragOver ]

在置放目標界限內拖曳 (移動) 物件時會持續發生這個事件。 這是反昇事件。

[ E:System.Windows.DragDrop.Drop ]

當物件放入置放目標時會發生這個事件。 這是反昇事件。

[ E:System.Windows.DragDrop.PreviewDragEnter ]

DragEnter 的通道版本。

[ E:System.Windows.DragDrop.PreviewDragLeave ]

DragLeave 的通道版本。

[ E:System.Windows.DragDrop.PreviewDragOver ]

DragOver 的通道版本。

[ E:System.Windows.DragDrop.PreviewDrop ]

Drop 的通道版本。

若要針對某個物件的執行個體處理施放事件,請為先前各表格中列出的事件加入處理常式。 若要在類別層級處理拖放事件,請覆寫對應的虛擬 On*Event 和 On*PreviewEvent 方法。 如需詳細資訊,請參閱控制項基底類別的路由事件類別處理

實作拖放功能

UI 項目可以是拖曳來源、置放目標或兩者都是。 若要實作基本拖放功能,請撰寫程式碼來啟始拖放作業和處理所放置的資料。 您可以處理選擇性拖放事件來增強拖放效果。

若要實作基本拖放功能,您需要完成下列工作:

  • 識別要做為拖曳來源的項目。 拖曳來源可以是 UIElementContentElement

  • 在將會負責啟始拖放作業的拖曳來源上建立事件處理常式。 事件通常是 MouseMove 事件。

  • 在拖曳來源的事件處理常式中,呼叫 DoDragDrop 方法來啟始拖放作業。 在 DoDragDrop 呼叫中,指定拖曳來源、要轉送的資料及允許的效果。

  • 識別要做為置放目標的項目。 置放目標可以是 UIElementContentElement

  • 將置放目標上的 AllowDrop 屬性設定為 true。

  • 在置放目標中,建立 Drop 事件處理常式來處理所放置的資料。

  • Drop 事件處理常式中使用 GetDataPresentGetData 方法,從 DragEventArgs 擷取資料。

  • Drop 事件處理常式中,使用該資料執行所需的拖放作業。

您可以透過建立自訂的 DataObject,以及透過處理選擇性的拖曳來源和置放目標事件,以增強拖放效果,如下列工作所示:

  • 若要轉送自訂資料或多個資料項目,請建立 DataObject 來傳遞給 DoDragDrop 方法。

  • 若要在拖曳期間執行其他動作,請在置放目標上處理 DragEnterDragEnterDragEnter 事件。

  • 若要變更滑鼠指標的外觀,請在拖曳來源上處理 GiveFeedback 事件。

  • 若要變更取消拖放作業的方式,請在拖曳來源上處理 QueryContinueDrag 事件。

拖放範例

本節說明如何實作 Ellipse 項目的拖放。 Ellipse 同時是拖曳來源和置放目標。 轉送的資料是這個橢圓形的 Fill 屬性的字串表示。 下列 XAML 顯示 Ellipse 項目和其所處理的拖放相關事件。 如需完整實作拖放的步驟,請參閱逐步解說:在使用者控制項上啟用拖放功能

啟用項目做為拖曳來源

做為拖曳來源的物件必須負責:

  • 識別拖曳的發生。

  • 啟始拖放作業。

  • 識別要轉送的資料。

  • 指定允許拖放作業在所轉送資料上的效果。

拖曳來源也可以提供回應給使用者來指出允許的動作 (移動、複製、無),而且可以根據使用者所做的其他輸入 (例如在拖曳期間按 ESC 鍵) 取消拖放作業。

您的應用程式必須負責判斷拖曳的發生,然後呼叫 DoDragDrop 方法啟始拖放作業。 這通常是按住滑鼠按鈕的情況下拖曳項目而發生 MouseMove 事件時。 下列範例顯示如何從 Ellipse 項目的 MouseMove 事件處理常式啟始拖放作業,使該項目成為拖曳來源。 轉送的資料是這個橢圓形的 Fill 屬性的字串表示。

MouseMove 事件處理常式內,呼叫 DoDragDrop 方法來啟始拖放作業。 DoDragDrop 方法接受三個參數:

  • dragSource – 所轉送資料的來源相依性物件的參考。這通常是 MouseMove 事件的來源。

  • data - 包含所轉送資料 (包裝在 DataObject 中) 的物件。

  • allowedEffects - 一個 DragDropEffects 列舉值,指定允許的拖放作業效果。

任何序列化物件都可以放在 data 參數中傳遞。 如果資料尚未包裝在 DataObject 中,則會自動將資料包裝在新的 DataObject 中。 若要傳遞多個資料項目,您必須自行建立 DataObject,並且將它傳遞給 DoDragDrop 方法。 如需詳細資訊,請參閱資料與資料物件

allowedEffects 參數用來指定拖曳來源將允許置放目標對所轉送的資料進行何種處理。 對於拖曳來源而言,常見的值為 CopyMoveAll

注意事項注意事項

置放目標也能夠指定在回應所放置的資料時想要達到的效果。例如,置放目標如果無法辨認要放置的資料型別,可以將允許效果設定為 None 來拒絕資料。它通常是在 DragOver 事件處理常式中執行這個動作。

拖曳來源可以選擇性地處理 GiveFeedbackQueryContinueDrag 事件。 這些事件具有預設處理常式,除非您將事件標記為已處理,否則會使用這些預設處理常式。 除非您特別需要變更這些事件的預設行為,否則您通常會忽略這些事件。

將拖曳來源進行拖曳時會持續引發 GiveFeedback 事件。 這個事件的預設處理常式會檢查拖曳來源是否疊到有效的置放目標上。 如果是,則會檢查置放目標允許的效果。 接著提供關於允許之放置效果的回應給使用者。 方法通常是將滑鼠指標變更為禁止放置、複製或移動游標。 只有在您需要使用自訂游標向使用者顯示回應時,才應該處理這個事件。 如果您處理這個事件,請記得將它標記為已處理,預設處理常式才不會覆寫您的處理常式。

將拖曳來源進行拖曳時會持續引發 QueryContinueDrag 事件。 您可以處理這個事件,以根據 ESC、SHIFT、CTRL 與 ALT 鍵和滑鼠按鈕的狀態,判斷使拖放作業結束的動作。 這個事件的預設處理常式會在按下 ESC 鍵時取消拖放作業,而在放開滑鼠按鈕時放置資料。

注意事項警告

拖放作業期間會持續引發這些事件。因此,您應該避免在事件處理常式中執行耗用大量資源的工作。例如,請使用快取游標,而非在每次引發 GiveFeedback 事件時都建立新游標。

啟用項目做為置放目標

做為置放目標的物件必須負責:

  • 指定它是有效的置放目標。

  • 回應拖曳至目標上的拖曳來源。

  • 檢查所轉送的資料是可以接收的格式。

  • 處理所放置的資料。

若要指定項目為置放目標,您需要將其 AllowDrop 屬性設定為 true。 之後該項目上就會引發置放目標事件讓您可以處理。 在拖放作業期間,置放目標上會發生下列順序的事件:

  1. [ E:System.Windows.DragDrop.DragEnter ]

  2. [ E:System.Windows.DragDrop.DragOver ]

  3. DragLeaveDrop

當資料被拖曳入置放目標界限內時會發生 DragEnter 事件。 如果適用於您的應用程式,您通常會處理這個事件來提供拖放作業的效果預覽。 請不要在 DragEnter 事件中設定 DragEventArgs.Effects 屬性,因為 DragOver 事件中會覆寫這個屬性。

下列範例顯示 Ellipse 項目的 DragEnter 事件處理常式。 這段程式碼會儲存目前的 Fill 筆刷,以預覽拖放作業的效果。 它接著會使用 GetDataPresent 方法,檢查被拖曳到橢圓形上的 DataObject 是否包含可以轉換為 Brush 的字串資料。 如果是的話,則會使用 GetData 方法擷取資料。 然後將資料轉換為 Brush 並套用至橢圓形。 DragLeave 事件處理常式中會還原這項變更。 如果資料無法轉換成 Brush,則不會執行任何動作。

在置放目標上拖曳資枓時會持續發生 DragOver 事件。 這個事件與拖曳來源上的 GiveFeedback 事件配對。 在 DragOver 事件處理常式中,您通常會使用 GetDataPresentGetData 方法檢查所轉送的資料是否為置放目標可處理的格式。 您也可以檢查是否已按下輔助按鍵,輔助按鍵通常指出使用者是想要執行移動還是複製動作。 執行這些檢查之後,您會設定 DragEventArgs.Effects 屬性,向拖曳來源通知放置資料將有什麼效果。 拖曳來源在 GiveFeedback 事件引數中接收這項資訊,而可以設定適當的游標來提供回應給使用者。

下列範例顯示 Ellipse 項目的 DragOver 事件處理常式。 這段程式碼會檢查被拖曳到橢圓形上的 DataObject 是否包含可以轉換為 Brush 的字串資料。 如果是的話,則會將 DragEventArgs.Effects 屬性設定為 Copy。 對拖曳來源而言,這表示資料可以複製到橢圓形。 如果資料無法轉換成 Brush,則 DragEventArgs.Effects 屬性會設定為 None。 對拖曳來源而言,這表示橢圓形不是資料的有效置放目標。

當資料被拖曳至目標界限外 (但沒有被放置) 時,會發生 DragLeave 事件。 您可以處理這個事件,以取消您在 DragEnter 事件處理常式中執行的任何動作。

下列範例顯示 Ellipse 項目的 DragLeave 事件處理常式。 這段程式碼會將儲存的 Brush 套用至橢圓形,以取消在 DragEnter 事件處理常式中執行的預覽。

當資料被放置到置放目標上時會發生 Drop 事件。根據預設,這是在放開滑鼠按鈕時發生。 在 Drop 事件處理常式中,您可以使用 GetData 方法,從 DataObject 擷取所轉送的資料,並且執行應用程式所需的任何資料處理。 Drop 事件會使拖放作業結束。

下列範例顯示 Ellipse 項目的 Drop 事件處理常式。 這段程式碼會套用拖放作業的效果,而且與 DragEnter 事件處理常式中的程式碼類似。 它會檢查被拖曳到橢圓形上的 DataObject 是否包含可以轉換為 Brush 的字串資料。 如果是的話,則將 Brush 套用至橢圓形。 如果資料無法轉換成 Brush,則不會執行任何動作。

請參閱

參考

Clipboard

其他資源

逐步解說:在使用者控制項上啟用拖放功能

拖放 HOW TO 主題

拖放

變更記錄

日期

記錄

原因

2011 年 4 月

更新主題。

客戶回函。