次の方法で共有


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

更新 : 2011 年 4 月

ここでは、Windows Presentation Foundation (WPF) アプリケーションにおけるドラッグ アンド ドロップ サポートの概要について説明します。 ドラッグ アンド ドロップとは、一般的に、マウス (またはその他のポインティング デバイス) を使用して 1 つ以上のオブジェクトを選択し、それらのオブジェクトをuser interface (UI) の目的のドロップ ターゲット上にドラッグしてドロップするデータ転送方法のことです。

このトピックは、次のセクションで構成されています。

  • WPF におけるドラッグ アンド ドロップ サポート
  • データ転送
  • ドラッグ アンド ドロップ イベント
  • ドラッグ アンド ドロップの実装
  • ドラッグ アンド ドロップの例
  • 関連トピック

WPF におけるドラッグ アンド ドロップ サポート

通常、ドラッグ アンド ドロップ操作には、ドラッグされるオブジェクトが存在するドラッグ ソースとドロップされるオブジェクトを受け取るドロップ ターゲットが含まれます。 ドラッグ ソースとドロップ ターゲットは、同じアプリケーションの UI 要素のことも別のアプリケーションの UI 要素のこともあります。

ドラッグ アンド ドロップで操作できるオブジェクトの種類と数は、完全に任意です。 たとえば、ドラッグ アンド ドロップで操作される一般的なオブジェクトには、ファイル、フォルダー、コンテンツの選択項目などがあります。

ドラッグ アンド ドロップ操作中に実行される特定のアクションはアプリケーション固有で、多くの場合、コンテキストで決定されます。 たとえば、同じストレージ デバイス上のフォルダー間で選択したファイルをドラッグすると、ファイルは既定で移動されますが、Universal Naming Convention (UNC) 共有からローカル フォルダーにファイルをドラッグすると、ファイルは既定でコピーされます。

WPF で提供されるドラッグ アンド ドロップ機能は、さまざまなドラッグ アンド ドロップのシナリオをサポートするように、高い柔軟性を備えたカスタマイズ可能な設計になっています。 ドラッグ アンド ドロップでは、単一のアプリケーション内または異なるアプリケーション間のオブジェクトの操作がサポートされます。 WPF アプリケーションと他の Windows アプリケーションの間でのドラッグ アンド ドロップも完全にサポートされます。

WPF では、すべての UIElement または ContentElement がドラッグ アンド ドロップに参加できます。 ドラッグ アンド ドロップ操作に必要なイベントおよびメソッドは、DragDrop クラスで定義されます。 UIElement クラスおよび ContentElement クラスには、DragDrop 添付イベントのエイリアスを格納します。これにより、UIElement または ContentElement が基本要素として継承されたときに、イベントがクラス メンバー リストに表示されます。 これらのイベントにアタッチされたイベント ハンドラーは、基になる DragDrop 添付イベントにアタッチされ、同じイベント データ インスタンスを受け取ります。 詳細については、UIElement.Drop イベントのトピックを参照してください。

セキュリティに関するメモセキュリティに関するメモ

OLE ドラッグ アンド ドロップは、インターネット ゾーンでは機能しません。

データ転送

ドラッグ アンド ドロップは、データ転送のより一般的な分野です。 データ転送には、ドラッグ アンド ドロップ操作とコピー/貼り付け操作が含まれます。 ドラッグ アンド ドロップ操作は、システムのクリップボードを使用してオブジェクトまたはアプリケーションの間でデータを転送するためのコピー/貼り付け操作または切り取り/貼り付け操作と似ています。 どちらの操作も、次の要素が必要になります。

  • データを提供するソース オブジェクト。

  • 転送されたデータを一時的に格納する方法。

  • データを受け取るターゲット オブジェクト。

コピー/貼り付け操作では、転送されたデータを一時的に格納するためにシステム クリップボードが使用されます。ドラッグ アンド ドロップ操作では、データを格納するために DataObject が使用されます。 概念上、データ オブジェクトは、実際のデータを格納する Object と対応するデータ形式識別子の 1 つ以上のペアで構成されます。

ドラッグ ソースは、静的 DragDrop.DoDragDrop メソッドを呼び出し、転送されたデータをこのメソッドに渡すことによって、ドラッグ アンド ドロップ操作を開始します。 DoDragDrop メソッドは、必要に応じてデータを自動的に DataObject にラップします。 データ形式をより細かく制御できるように、データを DataObject にラップしてから DoDragDrop メソッドに渡すことができます。 DataObject からデータを抽出するのはドロップ ターゲットの役割です。 データ オブジェクトの操作の詳細については、「データとデータ オブジェクト」を参照してください。

ドラッグ アンド ドロップ操作のソースとターゲットは UI 要素です。ただし、通常、実際に転送されるデータは視覚的表現を持ちません。 エクスプローラーでファイルをドラッグしているときに発生するようなドラッグ中のデータの視覚的表現を提供するコードを書くこともできます。 既定では、ドラッグ アンド ドロップ操作がデータに与える影響 (たとえば、データが移動されるのかまたはコピーされるのか) を表すようにカーソルを変化させることによってユーザーへのフィードバックが提供されます。

ドラッグ アンド ドロップの効果

ドラッグ アンド ドロップ操作では、転送されたデータに対して異なる効果を適用することができます。 たとえば、データをコピーしたり移動したりできます。 WPF では、ドラッグ アンド ドロップ操作の効果を指定するために使用できる DragDropEffects 列挙体が定義されています。 ドラッグ ソースでは、ソースで許容する効果を DoDragDrop メソッドに指定できます。 ドロップ ターゲットでは、ターゲットが意図している効果を DragEventArgs クラスの Effects プロパティに指定できます。 ドロップ ターゲットで意図している効果を DragOver イベントに指定すると、この情報が GiveFeedback イベントを使用してドラッグ ソースに返されます。 ドラッグ ソースは、この情報を使用して、ドロップ ターゲットで意図されているデータへの効果をユーザーに通知します。 データがドロップされると、ドロップ ターゲットは Drop イベントに実際の効果を指定します。 この情報は、DoDragDrop メソッドの戻り値としてドラッグ ソースに返されます。 ドラッグ ソースの allowedEffects のリストに含まれていない効果がドロップ ターゲットから返された場合、ドラッグ アンド ドロップ操作は取り消され、データ転送も行われません。

WPF では DragDropEffects 値はドラッグ ソースとドロップ ターゲットの間でドラッグ アンド ドロップ操作の効果に関する通信を提供するためにのみ使用されることを覚えておいてください。 ドラッグ アンド ドロップ操作の実際の効果は、アプリケーションに適切に記述されたコードに依存します。

たとえば、データをドロップしたときにデータを移動する効果がドロップ ターゲットで指定されているとします。 ただし、データを移動するには、ターゲット要素にデータを追加し、ソース要素からデータを削除する 2 つの操作が必要になります。 ソース要素でデータの移動を許容していたとしても、ソース要素からデータを削除するためのコードを記述していない場合、結果的にデータはコピーされるのみで、削除されません。

ドラッグ アンド ドロップ イベント

ドラッグ アンド ドロップ操作では、イベント ドリブン モデルがサポートされます。 ドラッグ ソースとドロップ ターゲットの両方で、ドラッグ アンド ドロップ操作を処理するために標準イベント セットが使用されます。 標準ドラッグ アンド ドロップ イベントの概要を次の表に示します。 これらは、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 要素は、ドラッグ ソース、ドロップ ターゲット、またはその両方に使用できます。 基本的なドラッグ アンド ドロップを実装するには、ドラッグ アンド ドロップ操作を開始するコードと、ドロップされたデータを処理するコードを記述します。 オプションのドラッグ アンド ドロップ イベントを処理することにより、ドラッグ アンド ドロップ エクスペリエンスを向上させることができます。

基本的なドラッグ アンド ドロップを実装するには、次のタスクを実行します。

  • ドラッグ ソースとなる要素を識別します。 ドラッグ ソースは、UIElement または ContentElement のいずれかです。

  • ドラッグ ソースで、ドラッグ アンド ドロップ操作を開始するイベント ハンドラーを作成します。 通常、このイベントは MouseMove イベントです。

  • ドラッグ ソースのイベント ハンドラーで、DoDragDrop を呼び出してドラッグ アンド ドロップ操作を開始します。 DoDragDrop 呼び出しで、ドラッグ ソース、転送するデータ、および許容される効果を指定します。

  • ドロップ ターゲットとなる要素を識別します。 ドロップ ターゲットは、UIElement または ContentElement のいずれかです。

  • ドロップ ターゲットで、AllowDrop プロパティを true に設定します。

  • ドロップ ターゲットで、ドロップされたデータを処理するための Drop イベント ハンドラーを作成します。

  • Drop イベント ハンドラーで、GetDataPresent メソッドと GetData メソッドを使用して、DragEventArgs からデータを抽出します。

  • Drop イベント ハンドラーで、データを使用して目的のドラッグ アンド ドロップ操作を実行します。

ドラッグ アンド ドロップ実装を強化するには、次のようにカスタム DataObject を作成し、オプションのドラッグ ソース イベントおよびドロップ ターゲット イベントを処理します。

  • カスタム データまたは複数のデータ項目を転送するには、DoDragDrop メソッドに渡す DataObject を作成します。

  • ドラッグ中に追加のアクションを実行するには、ドロップ ターゲットで DragEnterDragEnter、および DragEnter の各イベントを処理します。

  • マウス ポインターの外観を変更するには、ドラッグ ソースで GiveFeedback イベントを処理します。

  • ドラッグ アンド ドロップ操作を取り消す方法を変更するには、ドラッグ ソースで QueryContinueDrag イベントを処理します。

ドラッグ アンド ドロップの例

ここでは、Ellipse 要素のドラッグ アンド ドロップを実装する方法について説明します。 Ellipse は、ドラッグ ソースとドロップ ターゲットのどちらにもなります。 転送されるデータは、楕円の Fill プロパティの文字列形式です。 次の XAML に、Ellipse 要素と、処理されるドラッグ アンド ドロップ関連イベントを示します。 ドラッグ アンド ドロップを実装するための完全な手順については、「チュートリアル: ユーザー コントロールでのドラッグ アンド ドロップの有効化」を参照してください。

要素をドラッグ ソースとして使用可能にする

ドラッグ ソースであるオブジェクトは、次の役割を負います。

  • ドラッグの発生を識別する。

  • ドラッグ アンド ドロップ操作を開始する。

  • 転送するデータを識別する。

  • ドラッグ アンド ドロップ操作で転送するデータに許容される効果を指定する。

また、ドラッグ ソースでは、許容されるアクション (移動、コピー、なし) に関してユーザーにフィードバックを返すことができるほか、追加のユーザー入力 (ドラッグ中の Esc キーの押下など) に基づいてドラッグ アンド ドロップ操作を取り消すことができます。

ドラッグの発生を識別し、DoDragDrop メソッドを呼び出してドラッグ アンド ドロップ操作を開始するのは、アプリケーションの役割です。 通常、これは、マウス ボタンが押されている間に、ドラッグされる要素で MouseMove イベントが発生したときです。 Ellipse 要素の MouseMove イベント ハンドラーからドラッグ アンド ドロップ操作を開始してドラッグ ソースを設定する方法を次の例に示します。 転送されるデータは、楕円の Fill プロパティの文字列形式です。

MouseMove イベント ハンドラーで DoDragDrop メソッドを呼び出して、ドラッグ アンド ドロップ操作を開始します。 DoDragDrop メソッドは、次の 3 つのパラメーターを受け取ります。

  • dragSource: 転送されるデータのソースである依存関係オブジェクトの参照。通常は、MouseMove イベントのソースです。

  • data: DataObject にラップされて転送されるデータを格納するオブジェクト。

  • allowedEffects: ドラッグ アンド ドロップ操作の許容される効果を指定する DragDropEffects 列挙値の 1 つ。

すべてのシリアル化可能なオブジェクトは、data パラメーターで渡すことができます。 DataObject にラップされていないデータは、新しい DataObject に自動的にラップされます。 複数のデータ項目を渡するには、自分で DataObject を作成し、これを DoDragDrop メソッドに渡す必要があります。 詳細については、「データとデータ オブジェクト」を参照してください。

allowedEffects パラメーターは、ドラッグ ソースがドロップ ターゲットに対して許容する転送データの操作を指定するために使用します。 ドラッグ ソースに対して一般的に使用する値は、CopyMove、および All です。

メモメモ

ドロップ ターゲットでは、ドロップされるデータに対して適用する効果を指定することもできます。たとえば、許容される効果を None に設定すると、ドロップ ターゲットがドロップされるデータの型を識別できない場合にそのデータを拒否することができます。この操作は、通常、DragOver イベント ハンドラーで行います。

ドラッグ ソースでは、オプションで GiveFeedback イベントおよび QueryContinueDrag イベントを処理できます。 これらのイベントには、イベントを処理済みとしてマークしない限り使用される既定のハンドラーがあります。 特にこの既定動作を変更する必要がない限り、通常はこれらのイベントを無視します。

GiveFeedback イベントは、ドラッグ ソースがドラッグされている間、連続的に発生します。 このイベントの既定のハンドラーは、ドラッグ ソースが有効なドロップ ターゲット上にあるかどうかを調べます。 ドラッグ ソースが有効なドロップ ターゲット上にある場合、ハンドラーは、ドロップ ターゲットで許容される効果を調べます。 次に、ハンドラーは、許容される効果に関するフィードバックをエンド ユーザーに返します。 フィードバックの方法として、通常は、マウス カーソルをドロップなし、コピー、または移動を示す形に変更します。 このイベントを処理する必要があるのは、ユーザーにフィードバックを提供する際にカスタム カーソルを使用する場合だけです。 このイベントを処理する場合は、既定のハンドラーによってハンドラーがオーバーライドされないように、必ず処理済みとしてマークしてください。

QueryContinueDrag イベントは、ドラッグ ソースがドラッグされている間、連続的に発生します。 このイベントを処理することにより、Esc キー、Shift キー、Ctrl キー、および Alt キーの状態およびマウス ボタンの状態に基づいて、ドラッグ アンド ドロップ操作を終了するアクションを指定できます。 このイベントの既定のハンドラーは、Esc キーが押されるとドラッグ アンド ドロップ操作を取り消し、マウス ボタンが離されるとデータをドロップします。

Caution メモ注意

これらのイベントは、ドラッグ アンド ドロップ操作の間、連続的に発生します。したがって、イベント ハンドラーでリソースを大量に使用するタスクを使用しないように注意する必要があります。たとえば、GiveFeedback イベントが発生するたびに新しいカーソルを作成する代わりに、キャッシュされたカーソルを使用するようにします。

要素をドロップ ターゲットとして使用可能にする

ドロップ ターゲットであるオブジェクトは、次の役割を負います。

  • 有効なドロップ ターゲットであることを指定する。

  • ドラッグ ソースがターゲット上にドラッグされたときに応答する。

  • 転送されるデータが受け取り可能な形式であるかどうかを調べる。

  • ドロップされたデータを処理する。

要素をドロップ ターゲットとして指定するには、その AllowDrop プロパティを true に設定します。 次に、要素で発生するドロップ ターゲットのイベントを処理します。 ドラッグ アンド ドロップ操作の間、ドロップ ターゲットで次の一連のイベントが発生します。

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

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

  3. DragLeave または Drop

DragEnter イベントは、データがドロップ ターゲットの境界内にドラッグされると発生します。 通常は、このイベントを処理して、ドラッグ アンド ドロップ操作の効果のプレビューを提供します (アプリケーションで適切な場合)。 DragEventArgs.Effects プロパティは DragEnter イベントで設定しないでください。そうした場合、このプロパティは DragOver イベントで上書きされます。

Ellipse 要素の DragEnter イベント ハンドラーを次の例に示します。 このコードでは、現在の Fill ブラシを保存して、ドラッグ アンド ドロップ操作の効果のプレビューを提供します。 次に、GetDataPresent メソッドを使用して、楕円上にドラッグされている DataObject に、Brush に変換できる文字列データが含まれているかどうかを調べます。 文字列データが含まれる場合、GetData メソッドを使用してデータを抽出します。 次に、データを Brush に変換して楕円に適用します。 この変更は、DragLeave イベント ハンドラーで元に戻されます。 データを Brush に変換できない場合、アクションは実行されません。

DragOver イベントは、データがドロップ ターゲット上にドラッグされている間、連続的に発生します。 このイベントは、ドラッグ ソースの GiveFeedback イベントとペアになっています。 通常、DragOver イベント ハンドラーでは、GetDataPresent メソッドと GetData メソッドを使用して、転送されるデータがドロップ ターゲットで処理できる形式であるかどうかを調べします。 さらに、修飾子キーが押されたかどうかを調べることもできます。多くの場合、これによって、ユーザーが移動とコピーのどちらのアクションを行おうとしているかを判断できます。 これらのチェックを実行した後、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

その他の技術情報

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

ドラッグ アンド ドロップに関する「方法」トピック

ドラッグ アンド ドロップ

履歴の変更

日付

履歴

理由

2011 年 4 月

トピックを更新しました。

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