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

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

このトピックには次のセクションが含まれています。

  • WPF におけるドラッグ アンド ドロップ サポート
  • データとデータ オブジェクト
  • ドラッグ アンド ドロップ イベント
  • データ オブジェクトの操作
  • 関連トピック

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

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

ドラッグ アンド ドロップで操作できるオブジェクトの種類と数は、完全に任意です。ドラッグ アンド ドロップで操作される一般的なオブジェクトには、1 つ以上のファイルまたはフォルダやコンテンツの選択項目などがあります。ドラッグ アンド ドロップ操作中に実行される特定のアクションはアプリケーション固有で、多くの場合、コンテキストで決定されます。たとえば、同じストレージ デバイス上のフォルダ間で選択したファイルをドラッグすると、ファイルは既定で移動されますが、汎用名前付け規則 (UCS) 共有からローカル フォルダにファイルをドラッグすると、ファイルは既定でコピーされます。WPF で提供されるドラッグ アンド ドロップ機能は、さまざまなドラッグ アンド ドロップのシナリオをサポートするように、高い柔軟性を備えたカスタマイズ可能な設計になっています。ドラッグ アンド ドロップでは、単一のアプリケーション内または異なるアプリケーション間のオブジェクトの操作がサポートされます。WPF アプリケーションとその他の Windows アプリケーション間のドラッグ アンド ドロップも完全にサポートされています。ドラッグ アンド ドロップは、データ転送のより一般的な分野に分類されます。データ転送には、ドラッグ アンド ドロップに加えて、システム クリップボードを使用したコピーと貼り付けの操作も含まれます。

セキュリティに関するメモ : OLE ドラッグ アンド ドロップは、インターネット ゾーンでは機能しません。

データとデータ オブジェクト

ドラッグ アンド ドロップ操作の一部として転送されるデータは、データ オブジェクトに格納されます。概念上、データ オブジェクトは、次の項目の 1 つ以上のペアで構成されます。

  • 実際のデータを格納する Object

  • 対応するデータ形式の識別子。

データ自体は、基本 Object として表すことができる任意の項目で構成できます。対応するデータ形式は、データの形式に関するヒントを提供する文字列または Type です。データ オブジェクトは、データとデータ形式の複数ペアのホストをサポートします。これにより、単一のデータ オブジェクトでデータを複数の形式で提供できます。

すべてのデータ オブジェクトで、IDataObject インターフェイスを実装する必要があります。このインターフェイスは、データ転送を可能にし、容易にする次の標準メソッド セットを提供します。

メソッド 概要

GetData

データ オブジェクトを指定したデータ形式で取得します。

GetDataPresent

データが指定した形式で使用可能かどうか、または指定した形式に変換可能かどうかをチェックします。

GetFormats

このデータ オブジェクトのデータが格納されているか、または変換可能である形式のリストを返します。

SetData

指定したデータをこのデータ オブジェクトに格納します。

WPF は、DataObject クラスの IDataObject の基本実装を提供します。多くの一般的なデータ転送シナリオでは、標準の DataObject クラスで十分です。

WPF で提供される定義済みのデータ形式については、DataFormats クラスのリファレンス トピックを参照してください。

一般的に、データ オブジェクトには、データの抽出時にある形式で格納されているデータを別の形式に自動的に変換する機能が含まれています。この機能は自動変換と呼ばれます。

データ オブジェクトで使用できるデータ形式を照会するときに、GetFormats または GetDataPresent メソッドを呼び出して autoConvert パラメータを false に指定することで、自動変換可能なデータ形式をネイティブ データ形式からフィルタ処理することができます。SetData メソッドを使用してデータをデータ オブジェクトに追加する場合、autoConvert パラメータを false に設定してデータの自動変換を禁止することができます。

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

ドラッグ アンド ドロップ操作では、イベント ドリブン モデルがサポートされます。ドラッグ ソースとドロップ ターゲットの両方で、ドラッグ アンド ドロップ操作を処理するために標準イベント セットが使用されます。標準ドラッグ アンド ドロップ イベントの概要を次の表に示します。

ドラッグ ソース イベント

イベント 概要

GiveFeedback

このイベントは、ドラッグ アンド ドロップ操作が開始されたときに発生し、ドロップ ターゲットがドロップ ソースにフィードバック情報を送信できるようにします。このフィードバックは一般的に、ドラッグ ソースがマウス ポインタの外観を動的に調整し、ユーザーにフィードバックを提供するために使用されます。これは、バブル イベントです。

QueryContinueDrag

このイベントは、ドラッグ アンド ドロップ操作中にキーボードまたはマウス ボタンの状態が変更されると発生し、ドロップ ソースがキーまたはボタンの状態に応じてドラッグ アンド ドロップ操作をキャンセルできるようにします。これはバブル イベントです。

PreviewGiveFeedback

GiveFeedback のトンネル バージョン。

PreviewQueryContinueDrag

QueryContinueDrag のトンネル バージョン。

ドロップ ターゲット イベント

イベント 概要

DragEnter

このイベントは、オブジェクトがドロップ ターゲットの境界内にドラッグされると発生します。これはバブル イベントです。

DragLeave

このイベントは、オブジェクトがドロップ ターゲットの境界外にドラッグされると発生します。これはバブル イベントです。

DragOver

このイベントは、オブジェクトがドロップ ターゲットの境界内でドラッグ (移動) されると発生します。これはバブル イベントです。

Drop

このイベントは、オブジェクトがドロップ ターゲット上にドロップされると発生します。これはバブル イベントです。

PreviewDragEnter

DragEnter のトンネル バージョン。

PreviewDragLeave

DragLeave のトンネル バージョン。

PreviewDragOver

DragOver のトンネル バージョン。

PreviewDrop

Drop のトンネル バージョン。

データ オブジェクトの操作

ここでは、データ オブジェクトを作成および操作する一般的な手法について説明します。

DataObject コンストラクタの使用

DataObject クラスは、新しい DataObject インスタンスに単一のデータとデータ形式のペアを容易に設定できるようにするいくつかのオーバーロードされたコンストラクタを提供します。

新しいデータ オブジェクトを作成し、オーバーロードされたこのコンストラクタのいずれか (DataObject) を使用して、文字列と指定したデータ形式でデータ オブジェクトを初期化するコード例を次に示します。ここでは、データ形式は文字列によって指定されます。DataFormats クラスは、事前定義されている一連の型文字列を提供します。既定では、格納されるデータの自動変換が有効です。

string stringData = "Some string data to store...";
string dataFormat = DataFormats.UnicodeText;
DataObject dataObject = new DataObject(dataFormat, stringData);

データ オブジェクトを作成するコードの例については、「方法 : データ オブジェクトを作成する」を参照してください。

複数の形式のデータの格納

単一のデータ オブジェクトに複数の形式でデータを格納できます。単一のデータ オブジェクト内で複数のデータ形式を戦略的に使用すると、単一のデータ形式のみを表す場合よりも、データ オブジェクトを幅広いドロップ ターゲットで使用できる可能性が高くなります。通常、ドラッグ ソースは潜在的なドロップ ターゲットで使用できるデータ形式に依存しない必要があることに注意してください。

次の例は、SetData メソッドを使用してデータを複数の形式のデータ オブジェクトに追加する方法を示しています。

DataObject dataObject = new DataObject();
string sourceData = "Some string data to store...";

// Encode the source string into Unicode byte arrays.
byte[] unicodeText = Encoding.Unicode.GetBytes(sourceData); // UTF-16
byte[] utf8Text = Encoding.UTF8.GetBytes(sourceData);
byte[] utf32Text = Encoding.UTF32.GetBytes(sourceData);

// The DataFormats class does not provide data format fields for denoting
// UTF-32 and UTF-8, which are seldom used in practice; the following strings 
// will be used to identify these "custom" data formats.
string utf32DataFormat = "UTF-32";
string utf8DataFormat  = "UTF-8";

// Store the text in the data object, letting the data object choose
// the data format (which will be DataFormats.Text in this case).
dataObject.SetData(sourceData);
// Store the Unicode text in the data object.  Text data can be automatically
// converted to Unicode (UTF-16 / UCS-2) format on extraction from the data object; 
// Therefore, explicitly converting the source text to Unicode is generally unnecessary, and
// is done here as an exercise only.
dataObject.SetData(DataFormats.UnicodeText, unicodeText);
// Store the UTF-8 text in the data object...
dataObject.SetData(utf8DataFormat, utf8Text);
// Store the UTF-32 text in the data object...
dataObject.SetData(utf32DataFormat, utf32Text);

データ オブジェクトで使用可能な形式の照会

単一のデータ オブジェクトに任意の数のデータ形式を含めることができるため、データ オブジェクトには、使用可能なデータ形式のリストを取得する機能が含まれています。

GetFormats オーバーロードを使用して、データ オブジェクトで使用可能なすべてのデータ形式 (ネイティブおよび自動変換可能の両方) を示す一連の文字列を取得するコード例を次に示します。

DataObject dataObject = new DataObject("Some string data to store...");

// Get an array of strings, each string denoting a data format
// that is available in the data object.  This overload of GetDataFormats
// returns all available data formats, native and auto-convertible.
string[] dataFormats = dataObject.GetFormats();

// Get the number of data formats present in the data object, including both
// auto-convertible and native data formats.
int numberOfDataFormats = dataFormats.Length;

// To enumerate the resulting array of data formats, and take some action when
// a particular data format is found, use a code structure similar to the following.
foreach (string dataFormat in dataFormats)
{
    if (dataFormat == DataFormats.Text)
    {
        // Take some action if/when data in the Text data format is found.
        break;
    }
    else if(dataFormat == DataFormats.StringFormat)
    {
        // Take some action if/when data in the string data format is found.
        break;
    }
}

データ オブジェクトで使用可能なデータ形式を照会するコードの例については、「方法 : データ オブジェクト内のデータ形式の一覧を表示する」を参照してください。特定のデータ形式が存在するかどうかをデータ オブジェクトに照会する例については、「方法 : データ形式がデータ オブジェクトに存在するかどうかを判別する」を参照してください。

データ オブジェクトからのデータの取得

データ オブジェクトから特定の形式のデータを取得するには、単に GetData メソッドのいずれかを呼び出して目的のデータ形式を指定します。GetDataPresent メソッドのいずれかを使用すると、特定のデータ形式が存在するかどうかを確認できます。GetData は、Object 内のデータを返します。データ形式に応じて、このオブジェクトを型固有のコンテナにキャストできます。

GetDataPresent オーバーロードを使用して、指定したデータ形式が (ネイティブで、または自動変換により) 使用可能かどうかを最初に確認するコード例を次に示します。指定した形式が使用可能な場合は、GetData メソッドを使用してデータを取得します。

DataObject dataObject = new DataObject("Some string data to store...");

string desiredFormat = DataFormats.UnicodeText;
byte[] data = null;

// Use the GetDataPresent method to check for the presence of a desired data format.
// This particular overload of GetDataPresent looks for both native and auto-convertible 
// data formats.
if (dataObject.GetDataPresent(desiredFormat))
{
    // If the desired data format is present, use one of the GetData methods to retrieve the
    // data from the data object.
    data = dataObject.GetData(desiredFormat) as byte[];
}

データ オブジェクトからデータを取得するコードの例については、「方法 : 特定のデータ形式でデータを取得する」を参照してください。

データ オブジェクトからのデータの削除

データは、データ オブジェクトから直接削除できません。データ オブジェクトからデータを事実上削除するには、次の推奨手順に従います。

 

  1. 保持するデータのみを含む新しいデータ オブジェクトを作成します。

  2. 古いデータ オブジェクトから新しいデータ オブジェクトに目的のデータを "コピー" します。データをコピーするには、GetData メソッドのいずれかを使用して未処理データを含む Object を取得し、SetData メソッドのいずれかを使用してデータを新しいデータ オブジェクトに追加します。

  3. 古いデータ オブジェクトを新しいデータ オブジェクトに置き換えます。

 

メモメモ :

SetData メソッドは、データ オブジェクトへのデータの追加のみを行います。データとデータ形式が前回の呼び出しとまったく同じ場合でも、データの置換は行いません。同じデータとデータ形式に対して SetData を 2 回呼び出すと、データとデータ形式がデータ オブジェクトに 2 回存在することになります。

参照

関連項目

Clipboard

その他の技術情報

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