次の方法で共有


チュートリアル: ユーザー コントロールでのドラッグ アンド ドロップの有効化

更新 : 2011 年 4 月

このチュートリアルでは、Windows Presentation Foundation (WPF) でドラッグ アンド ドロップによるデータ転送に参加できるカスタム ユーザー コントロールを作成する方法を説明します。

このチュートリアルでは、円を表すカスタム WPF UserControl を作成します。 コントロールに機能を実装して、ドラッグ アンド ドロップ操作でデータを転送できるようにします。 たとえば、ある Circle コントロールから別のコントロールにドラッグすると、塗りつぶしの色のデータがソースの Circle からターゲットにコピーされます。 Circle コントロールから TextBox にドラッグすると、塗りつぶしの色の文字列形式が TextBox にコピーされます。 2 つのパネル コントロールを含む小さなアプリケーションおよび TextBox も作成して、ドラッグ アンド ドロップ機能をテストします。 また、ドロップした Circle データをパネルで処理できるようにするコードを記述します。これにより、あるパネルの子コレクションから別の場所に Circle を移動またはコピーできるようになります。

このチュートリアルでは、次の作業について説明します。

  • カスタム ユーザー コントロールを作成する。

  • ユーザー コントロールがドラッグ ソースになるようにする。

  • ユーザー コントロールがドロップ ターゲットになるようにする。

  • ユーザー コントロールからドロップされたデータをパネルで受け取ることができるようにする。

必要条件

このチュートリアルを実行するには、次のコンポーネントが必要です。

  • Visual Studio 2010

アプリケーション プロジェクトの作成

このセクションでは、2 つのパネルを備えたメイン ページおよび TextBox が含まれるアプリケーション インフラストラクチャを作成します。

プロジェクトを作成するには

  1. Visual Basic または Visual C# で DragDropExample という名前の新しい WPF アプリケーション プロジェクトを作成します。 詳細については、「方法 : 新しい WPF アプリケーション プロジェクトを作成する」を参照してください。

  2. MainWindow.xaml を開きます。

  3. Grid の開始タグと終了タグの間に、次のマークアップを追加します。

    このマークアップは、テスト アプリケーションのユーザー インターフェイスを作成します。

プロジェクトへの新しいユーザー コントロールの追加

ここでは、プロジェクトに新しいユーザー コントロールを追加します。

新しいユーザー コントロールを追加するには

  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 ユーザー コントロールの 2 つのインスタンスを作成します。

    パネルの完全な XAML は次のようになります。

ユーザー コントロールでのドラッグ ソース イベントの実装

ここでは、ドラッグ ソースのイベント ハンドラーで、OnMouseMove メソッドをオーバーライドして、ドラッグ アンド ドロップ操作を開始します。

ドラッグを開始すると (マウス ボタンを押しながらマウスを動かすと)、転送するデータを DataObject にパッケージ化することになります。 ここでは、塗りつぶしの色の文字列形式、高さの double 型形式、およびコピーという 3 つのデータ項目を、Circle コントロールがパッケージ化します。

ドラッグ アンド ドロップ操作を開始するには

  1. Circle.xaml.cs または Circle.xaml.vb を開きます。

  2. 次の OnMouseMove オーバーライドを追加して、MouseMove イベントにクラス処理を提供します。

    この OnMouseMove オーバーライドは、次のタスクを実行します。

    • マウスを動かしながらマウスの左ボタンを押しているかどうかをチェックします。

    • Circle データを DataObject にパッケージ化します。 ここでは、塗りつぶしの色、高さの double 型形式、およびコピーという 3 つのデータ項目を、Circle コントロールがパッケージ化します。

    • ドラッグ アンド ドロップ操作を開始するための静的な DragDrop.DoDragDrop メソッドを呼び出します。 次の 3 つのパラメーターを DoDragDrop メソッドに渡します。

      • dragSource – このコントロールへの参照。

      • data – 前のコードで作成された DataObject

      • allowedEffects – 有効なドラッグ アンド ドロップ操作 (Copy または Move)。

  3. F5 キーを押してアプリケーションをビルドし、実行します。

  4. Circle コントロールを 1 つクリックして、パネル、他の 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、および TextBox の上に、Circle コントロールを 1 つドラッグします。 カーソルは、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. green というテキストを TextBox に入力します。

  7. TextBox で gre というテキストを選択します。

  8. このテキストを Circle コントロールにドラッグしてドロップします。 カーソルが変化し、ドロップが有効であることが示されますが、gre は有効な色ではないので Circle の色は変わりません。

  9. 緑の Circle コントロールからドラッグして、青の Circle コントロールにドロップします。 Circle が青から緑に変わります。 表示されるカーソルは、TextBox または Circle のどちらがドラッグ ソースであるかによって異なります。

ある要素をドロップ ターゲットにするために必要なことは、AllowDrop プロパティを true に設定し、ドロップされたデータを処理することです。 ただし、ユーザー エクスペリエンスを向上させるためには、DragEnterDragLeave、および DragOver の各イベントも処理する必要があります。 これらのイベントでは、データのドロップ前に、チェックを実行して追加のフィードバックをユーザーに提供することができます。

データが Circle ユーザー コントロール上にドラッグされると、このコントロールは、ドラッグされたデータが処理可能であるかどうかをドラッグ ソースに通知します。 このコントロールは、データの処理方法が不明な場合、ドロップを拒否します。 これを行うには、DragOver イベントを処理して、Effects プロパティを設定します。

データ ドロップが有効であることを確認するには

  1. Circle.xaml.cs または Circle.xaml.vb を開きます。

  2. 次の OnDragOver オーバーライドを追加して、DragOver イベントにクラス処理を提供します。

    この OnDragOver オーバーライドは、次のタスクを実行します。

    • Effects プロパティを None に設定します。

    • OnDrop メソッドの場合と同じチェックを実行して、ドラッグされたデータを Circle ユーザー コントロールで処理できるかどうかを判断します。

    • ユーザー コントロールでデータを処理できる場合は、Effects プロパティを Copy または Move に設定します。

  3. F5 キーを押してアプリケーションをビルドし、実行します。

  4. TextBox で gre というテキストを選択します。

  5. このテキストを Circle コントロールにドラッグします。 カーソルが変化し、ドロップが有効でないことが示されます。これは、gre が有効な色ではないためです。

ドロップ操作のプレビューを適用することにより、ユーザー エクスペリエンスをさらに向上させることができます。 Circle ユーザー コントロールについて、OnDragEnter メソッドと OnDragLeave メソッドをオーバーライドします。 データをコントロール上にドラッグしたときに、現在の背景の Fill がプレースホルダーの変数に保存されます。 その文字列がブラシに変換されて、Circle の UI を提供する Ellipse に適用されます。 データがドロップされることなく Circle の外へドラッグされると、元の Fill の値が Circle に再び適用されます。

ドラッグ アンド ドロップ操作の効果をプレビューするには

  1. Circle.xaml.cs または Circle.xaml.vb を開きます。

  2. Circle クラスで、_previousFill という名前のプライベート Brush 変数を宣言し、null に初期化します。

  3. 次の OnDragEnter オーバーライドを追加して、DragEnter イベントにクラス処理を提供します。

    この OnDragEnter オーバーライドは、次のタスクを実行します。

    • EllipseFill プロパティを _previousFill 変数に保存します。

    • 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 を移動すること、または Ctrl キーを押しながら Circle をドラッグ アンド ドロップして Circle コントロールのコピーを作成することを可能にするコードを実装します。

パネルがドロップ ターゲットになるようにするには

  1. MainWindow.xaml を開きます。

  2. 次の XAML に示すように、それぞれの StackPanel コントロールで、DragOver イベントおよび Drop イベント用のハンドラーを追加します。 DragOver イベント ハンドラーに panel_DragOver という名前、Drop イベント ハンドラーに panel_Drop という名前を付けます。

  3. MainWindows.xaml.cs または MainWindow.xaml.vb を開きます。

  4. DragOver イベント ハンドラーに次のコードを追加します。

    この DragOver イベント ハンドラーは、次のタスクを実行します。

    • Circle ユーザー コントロールによって DataObject にパッケージ化され、DoDragDrop の呼び出しに渡される "オブジェクト" データが、ドラッグされたデータに含まれていることをチェックします。

    • "オブジェクト" データがある場合は、Ctrl キーが押されているかどうかをチェックします。

    • Ctrl キーが押されている場合は、Effects プロパティを Copy に設定します。 それ以外の場合は、Effects プロパティを Move に設定します。

  5. Drop イベント ハンドラーに次のコードを追加します。

    この Drop イベント ハンドラーは、次のタスクを実行します。

    • Drop イベントが処理されたかどうかをチェックします。 たとえば、ある Circle が Drop イベントを処理する別の Circle 上にドロップされた場合、その Circle を含むパネルではイベントを処理しないようにしたいと考えるものです。

    • Drop イベントが処理されない場合は、Ctrl キーが押されているかどうかをチェックします。

    • Drop イベントの発生時に Ctrl キーが押されている場合は、Circle コントロールのコピーを作成して、StackPanelChildren コレクションに追加します。

    • Ctrl キーが押されていない場合は、Circle を親パネルの Children コレクションから、ドロップ先のパネルの Children コレクションに移動します。

    • Effects プロパティを設定して、移動操作またはコピー操作が実行されたことを DoDragDrop メソッドに通知します。

  6. F5 キーを押してアプリケーションをビルドし、実行します。

  7. TextBox で green というテキストを選択します。

  8. このテキストを Circle コントロール上にドラッグしてドロップします。

  9. Circle コントロールを左側のパネルから右側のパネルにドラッグしてドロップします。 Circle が、左側のパネルの Children コレクションから削除され、右側のパネルの子コレクションに追加されます。

  10. Ctrl キーを押しながら、Circle コントロールがあるパネルから別のパネルに Circle コントロールをドラッグしてドロップします。 Circle がコピーされ、そのコピーが、受け取る側のパネルの Children コレクションに追加されます。

参照

概念

ドラッグ アンド ドロップの概要

履歴の変更

日付

履歴

理由

2011 年 4 月

トピックを追加

カスタマー フィードバック