共用方式為


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

更新:2011 年 4 月

這個逐步解說會示範如何建立可在 Windows Presentation Foundation (WPF) 中參與拖放資料傳輸的自訂使用者控制項。

在此逐步解說中,您會建立一個代表圓形的自訂 WPF UserControl。 您會在此控制項上實作功能,以便透過拖放動作在其上進行資料傳輸。 例如,如果您從一個 Circle 控制項拖曳至另一個 Circle 控制項,便會從來源 Circle 複製填滿色彩資料至目標 Circle。 如果您從 Circle 控制項拖曳至 TextBox,則會將填滿色彩的字串表示複製至 TextBox。 您也將建立一個小型應用程式,其中包含兩個面板控制項和一個 TextBox,用來測試拖放功能。 您會撰寫程式碼,讓面板可以處理所放置的 Circle 資料,使您可以從一個面板的 Children 集合移動或複製 Circle 至另一個面板。

這個逐步解說將說明下列工作:

  • 建立自訂使用者控制項。

  • 啟用使用者控制項做為拖曳來源。

  • 啟用使用者控制項做為置放目標。

  • 啟用面板,接收從使用者控制項放置過來的資料。

必要條件

您需要下列元件才能完成此逐步解說:

  • Visual Studio 2010

建立應用程式專案

在本節中,您會建立應用程式基礎結構,包括一個內有兩個面板和一個 TextBox 的主頁面。

若要建立專案

  1. 在 Visual Basic 或 Visual C# 中,建立名為 DragDropExample 的新 WPF 應用程式專案。 如需詳細資訊,請參閱 HOW TO:建立新的 WPF 應用程式專案

  2. 開啟 MainWindow.xaml。

  3. 在開頭和結尾 Grid 標記 (Tag) 之間,加入下列標記 (Markup)。

    此標記 (Markup) 會建立測試應用程式的使用者介面。

將新的使用者控制項加入至專案

在本節中,您會將新的使用者控制項加入至專案。

若要加入新的使用者控制項

  1. 從 [專案] 功能表中選取 [加入使用者控制項]。

  2. 在 [加入新項目] 對話方塊中,將名稱變更為 Circle.xaml,然後按一下 [加入]。

    Circle.xaml 和它的程式碼後置就會加入至專案。

  3. 開啟 Circle.xaml。

    這個檔案包含使用者控制項的使用者介面項目。

  4. 將下列標記加入至根 Grid,建立有一個藍色圓形做為其 UI 的簡單使用者控制項。

  5. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  6. 在 C# 中,將下列程式碼加到預設建構函式後面,以建立複製建構函式。 在 Visual Basic 中,加入下列程式碼,以同時建立預設建構函式和複製建構函式。

    為了讓使用者控制項可以被複製,您會在程式碼後置檔案中加入複製建構函式方法。 在此簡化的 Circle 使用者控制項中,您只會複製使用者控制項的填滿和大小資料。

若要將使用者控制項加入至主視窗

  1. 開啟 MainWindow.xaml。

  2. 將下列 XAML 加入至開頭 Window 標記,以建立對目前應用程式的 XML 命名空間參考。

    xmlns:local="clr-namespace:DragDropExample"
    
  3. 在第一個 StackPanel 中,加入下列 XAML 以在第一個面板中建立 Circle 使用者控制項的兩個執行個體。

    此面板的完整 XAML 看起來如下所示。

在使用者控制項中實作拖曳來源事件

在本節中,您會覆寫 OnMouseMove 方法並啟始拖放作業。

如果有人開始拖曳 (按下滑鼠按鍵並移動滑鼠),要傳輸的資料會封裝成 DataObject。 在此例中,Circle 控制項會封裝三個資料項目:其填滿色彩的字串表示、其高度的雙精確度表示,以及本身複本。

若要啟始拖放作業

  1. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  2. 加入下列 OnMouseMove 覆寫,以提供 MouseMove 事件的類別處理。

    OnMouseMove 覆寫會執行下列工作:

    • 檢查當滑鼠移動時,是否已按下滑鼠左鍵。

    • 將 Circle 資料封裝成 DataObject。 在此例中,Circle 控制項會封裝三個資料項目:其填滿色彩的字串表示、其高度的雙精確度表示,以及本身複本。

    • 呼叫靜態 DragDrop.DoDragDrop 方法來啟始拖放作業。 您會將下列三個參數傳遞給 DoDragDrop 方法:

      • dragSource – 此控制項的參考。

      • data - 在先前程式碼中建立的 DataObject

      • allowedEffects – 允許進行的拖放作業,即 CopyMove

  3. 按 F5 建置並執行應用程式。

  4. 按其中一個 Circle 控制項,然後將它拖曳至面板、另一個 Circle,再到 TextBox。 拖曳至 TextBox 時,游標會改變以表示移動狀態。

  5. 將 Circle 拖曳至 TextBox 時,按住 CTRL 鍵。 請注意游標如何改變以表示複製狀態。

  6. 將 Circle 拖放至 TextBox。 Circle 填滿色彩的字串表示會附加至 TextBox

根據預設,拖放作業期間的游標會改變,以指出放置資料的效果將為何。 您可以處理 GiveFeedback 事件並設定不同游標,以自訂向使用者顯示的回應。

若要向使用者顯示回應

  1. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  2. 加入下列 OnGiveFeedback 覆寫,以提供 GiveFeedback 事件的類別處理。

    OnGiveFeedback 覆寫會執行下列工作:

    • 檢查置放目標之 DragOver 事件處理常式中設定的 Effects 值。

    • 根據 Effects 值來設定自訂游標。 游標是用來向使用者顯示放置資料將有之效果的視覺化回應。

  3. 按 F5 建置並執行應用程式。

  4. 拖曳其中一個 Circle 控制項至面板、另一個 Circle,再到 TextBox。 請注意,游標現在變成您在 OnGiveFeedback 覆寫中指定的自訂游標。

  5. TextBox 中選取文字 green。

  6. 將 green 文字拖曳至 Circle 控制項。 請注意,現在會顯示預設游標,以指出拖放作業的效果。 回應游標一律由拖曳來源設定。

在使用者控制項中實作置放目標事件

在本節中,您會指定使用者控制項做為置放目標、覆寫啟用使用者控制項做為置放目標的方法,並處理放置於其上的資料。

若要啟用使用者控制項做為置放目標

  1. 開啟 Circle.xaml。

  2. 在開頭 UserControl 標記中,加入 AllowDrop 屬性並設定為 true。

AllowDrop 屬性設為 true,而且拖曳來源的資料被放置在 Circle 使用者控制項上,就會呼叫 OnDrop 方法。 在這個方法中,您會處理所放置的資料並將資料套用至 Circle。

若要處理所放置的資料

  1. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  2. 加入下列 OnDrop 覆寫,以提供 Drop 事件的類別處理。

    OnDrop 覆寫會執行下列工作:

    • 使用 GetDataPresent 方法以檢查拖曳資料是否包含字串物件。

    • 使用 GetData 方法以擷取字串資料 (若有的話)。

    • 使用 BrushConverter 以嘗試將字串轉換為 Brush

    • 如果可以順利轉換,則將筆刷套用至提供 Circle 控制項 UI 之 EllipseFill

    • Drop 事件標記為已處理。 您應將置放事件標記為已處理,收到此事件的其他項目才會知道 Circle 使用者控制項已經處理該事件了。

  3. 按 F5 建置並執行應用程式。

  4. TextBox 中選取文字 green。

  5. 將文字拖曳至 Circle 控制項並放下。 Circle 會從藍色變更為綠色。

  6. TextBox 中輸入文字 green。

  7. TextBox 中選取文字 gre。

  8. 將它拖曳至 Circle 控制項並放下。 請注意游標會改變以表示允許放置動作,但 Circle 的色彩不會改變,因為 gre 不是有效顏色。

  9. 從綠色 Circle 控制項拖曳並放置到藍色 Circle 控制項上。 Circle 會從藍色變更為綠色。 請注意,所顯示的游標取決於拖曳來源是 TextBox 還是 Circle。

若要啟用項目做為置放目標,所需步驟只有將 AllowDrop 屬性設定為 true,以及處理所放置的資料。 不過,若想提供更佳的使用者體驗,您還應該處理 DragEnterDragLeaveDragOver 事件。 在這些事件中,您可以在放置資料前執行檢查,以及向使用者顯示其他回應。

將資料拖曳至 Circle 使用者控制項時,控制項應通知拖曳來源它是否可以處理所拖曳的資料。 如果控制項不知道如何處理資料,則應拒絕放置。 若要這麼做,您需要處理 DragOver 事件並設定 Effects 屬性。

若要確認允許資料放置

  1. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  2. 加入下列 OnDragOver 覆寫,以提供 DragOver 事件的類別處理。

    OnDragOver 覆寫會執行下列工作:

    • Effects 屬性設定為 None

    • 執行與 OnDrop 方法中相同的檢查,以判斷 Circle 使用者控制項是否可以處理所拖曳的資料。

    • 如果使用者控制項可以處理資料,則將 Effects 屬性設定為 CopyMove

  3. 按 F5 建置並執行應用程式。

  4. TextBox 中選取文字 gre。

  5. 將文字拖曳至 Circle 控制項。 請注意現在游標會改變以表示不允許放置動作,因為 gre 不是有效顏色。

您可以套用放置作業的預覽,進一步增強使用者體驗。 在 Circle 使用者控制項,您需要覆寫 OnDragEnterOnDragLeave 方法。 拖曳資料至控制項時,會將目前背景 Fill 儲存至預存位置變數。 接著會將字串轉換為筆刷,並套用至提供 Circle UI 的 Ellipse。 如果拖曳資料至 Circle 外 (但沒有放置),則會將原始 Fill 値重新套用至 Circle。

若要預覽拖放作業的效果

  1. 開啟 Circle.xaml.cs 或 Circle.xaml.vb。

  2. 在 Circle 類別中宣告名為 _previousFill 的私用 Brush 變數,並將它初始化為 null。

  3. 加入下列 OnDragEnter 覆寫,以提供 DragEnter 事件的類別處理。

    OnDragEnter 覆寫會執行下列工作:

    • 在 _previousFill 變數中儲存 EllipseFill 屬性。

    • 執行與 OnDrop 方法中相同的檢查,以判斷資料是否可以轉換成 Brush

    • 如果資料已轉換為有效 Brush,則將它套用至 EllipseFill

  4. 加入下列 OnDragLeave 覆寫,以提供 DragLeave 事件的類別處理。

    OnDragLeave 覆寫會執行下列工作:

    • 將 _previousFill 變數中儲存的 Brush,套用至提供 Circle 使用者控制項 UI 之 EllipseFill
  5. 按 F5 建置並執行應用程式。

  6. TextBox 中選取文字 green。

  7. 將文字拖曳至 Circle 控制項,但不放下。 Circle 會從藍色變更為綠色。

  8. 將文字拖曳離開 Circle 控制項。 Circle 會從綠色變回為藍色。

啟用面板以接收所置放的資料

在本節中,您會啟用裝載 Circle 使用者控制項的面板,做為所拖曳 Circle 資料的置放目標。 您會實作程式碼,讓您可以在不同面板間移動 Circle,或是透過在拖曳 Circle 同時按住 CTRL 鍵來複製 Circle 控制項。

若要啟用面板做為置放目標

  1. 開啟 MainWindow.xaml。

  2. 如下列 XAML 所示,在每個 StackPanel 控制項中,加入 DragOverDrop 事件的處理常式。 將 DragOver 事件處理常式命名為 panel_DragOver,並將 Drop 事件處理常式命名為 panel_Drop。

  3. 開啟 MainWindows.xaml.cs 或 MainWindow.xaml.vb。

  4. 將下列程式碼加入 DragOver 事件處理常式。

    DragOver 事件處理常式會執行下列工作:

    • 確定所拖曳資料是否包含 Circle 使用者控制項封裝在 DataObject 中,並在 DoDragDrop 呼叫中傳遞的 "Object" 資料。

    • 如果有 "Object" 資料,則檢查是否已按下 CTRL 鍵。

    • 如果已按下 CTRL 鍵,則將 Effects 屬性設定為 Copy。 否則,將 Effects 屬性設定為 Move

  5. 將下列程式碼加入 Drop 事件處理常式。

    Drop 事件處理常式會執行下列工作:

    • 檢查是否已經處理 Drop 事件。 例如,如果將 Circle 放置在另一個處理 Drop 事件的 Circle 上,您不會希望包含 Circle 的面板也對此事件進行處理。

    • 如果尚未處理 Drop 事件,檢查是否已按下 CTRL 鍵。

    • 如果當 Drop 發生時已按下 CTRL 鍵,則複製 Circle 控制項並將複本加入至 StackPanelChildren 集合。

    • 如果未按下 CTRL 鍵,則將 Circle 從其父面板的 Children 集合移動至放置此 Circle 所在之面板的 Children 集合。

    • 設定 Effects 屬性以通知 DoDragDrop 方法已執行移動或是複製作業。

  6. 按 F5 建置並執行應用程式。

  7. TextBox 中選取文字 green。

  8. 將文字拖曳至 Circle 控制項並放下。

  9. 從左面板拖曳 Circle 控制項至右面板並放下。 Circle 會從左面板的 Children 集合中移除,並加入至右面板的 Children 集合。

  10. 按住 CTRL 鍵,同時將 Circle 控制項從所在面板拖曳至另一個面板並放下。 如此會複製 Circle,並將複本加入至接收面板的 Children 集合。

請參閱

概念

拖放概觀

變更記錄

日期

記錄

原因

2011 年 4 月

加入主題。

客戶回函。