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

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

  • 実際のデータが含まれる Object

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

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

データ オブジェクト

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

メソッド まとめ
GetData 指定したデータ形式でデータ オブジェクトを取得します。
GetDataPresent データを指定した形式で使用できるかどうか、または指定した形式に変換できるかどうかを確認します。
GetFormats このデータ オブジェクトのデータが格納されている形式の一覧、または変換できる形式の一覧を返します。
SetData 指定したデータをこのデータ オブジェクトに格納します。

WPF では、DataObject クラスの IDataObject の基本的な実装が提供されます。 多くの一般的なデータ転送シナリオには、普通の DataObject クラスで十分です。

ビットマップ、CSV、ファイル、HTML、RTF、文字列、テキスト、オーディオなど、定義済みの形式がいくつかあります。 WPF で提供されている定義済みのデータ形式の詳細については、DataFormats クラスのリファレンス トピックを参照してください。

通常、データ オブジェクトには、データの抽出時にある形式で格納されたデータを別の形式に自動的に変換する機能が含まれています。この機能は、自動変換と呼ばれます。 データ オブジェクトで使用可能なデータ形式を問い合わせるときは、GetFormats(Boolean) メソッドまたは GetDataPresent(String, Boolean) メソッドを呼び出し、autoConvert パラメーターとして false を指定することにより、ネイティブ データ形式から自動変換可能なデータ形式をフィルターで除外できます。 SetData(String, Object, Boolean) メソッドを使用してデータ オブジェクトにデータを追加する場合、autoConvert パラメーターを false に設定することにより、データの自動変換を禁止できます。

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

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

新しいデータ オブジェクトの作成

DataObject クラスには複数のオーバーロードされたコンストラクターが用意されており、新しい DataObject インスタンスにデータとデータ形式の 1 つのペアを簡単に設定できます。

次のコード例では、新しいデータ オブジェクトを作成し、オーバーロードされたコンストラクター DataObject(DataObject(String, Object)) の 1 つを使用して、文字列と指定したデータ形式でデータ オブジェクトを初期化します。 この場合、データ形式は文字列で指定します。DataFormats クラスによって、事前に定義された型の文字列のセットが提供されます。 既定では、格納されたデータの自動変換は許可されています。

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

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

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

1 つのデータ オブジェクトに、複数の形式でデータを格納できます。 1 つのデータ オブジェクトへの複数のデータ形式の格納を戦略的に使用すると、データ オブジェクトが、1 つのデータ形式しか表現できない場合より、広範なドロップ ターゲットでデータ オブジェクトを使用できるようになる可能性があります。 一般に、ドラッグ元は、可能性のあるドロップ ターゲットで使用可能なデータ形式が何であっても対応できなければならないことに注意してください。

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

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);
Dim dataObject As New DataObject()
Dim sourceData As String = "Some string data to store..."

' Encode the source string into Unicode byte arrays.
Dim unicodeText() As Byte = Encoding.Unicode.GetBytes(sourceData) ' UTF-16
Dim utf8Text() As Byte = Encoding.UTF8.GetBytes(sourceData)
Dim utf32Text() As Byte = 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.
Dim utf32DataFormat As String = "UTF-32"
Dim utf8DataFormat As String = "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)

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

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

次のコード例では、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;
    }
}
Dim dataObject As 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.
Dim dataFormats() As String = dataObject.GetFormats()

' Get the number of data formats present in the data object, including both
' auto-convertible and native data formats.
Dim numberOfDataFormats As Integer = 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.
For Each dataFormat As String In dataFormats
    If dataFormat = System.Windows.DataFormats.Text Then
        ' Take some action if/when data in the Text data format is found.
        Exit For
    ElseIf dataFormat = System.Windows.DataFormats.StringFormat Then
        ' Take some action if/when data in the string data format is found.
        Exit For
    End If
Next dataFormat

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

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

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

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

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[];
}
Dim dataObject As New DataObject("Some string data to store...")

Dim desiredFormat As String = DataFormats.UnicodeText
Dim data() As Byte = Nothing

' 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) Then
    ' If the desired data format is present, use one of the GetData methods to retrieve the
    ' data from the data object.
    data = TryCast(dataObject.GetData(desiredFormat), Byte())
End If

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

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

データ オブジェクトからデータを直接削除することはできません。 データ オブジェクトからデータを効果的に削除するには、次の手順のようにします。

  1. 保持するデータだけが含まれる新しいデータ オブジェクトを作成します。

  2. 古いデータ オブジェクトから新しいデータ オブジェクトに必要なデータを "コピー" します。 データをコピーするには、GetData メソッドのいずれかを使用して、生データが含まれる Object を取得した後、SetData メソッドのいずれかを使用して、新しいデータ オブジェクトにデータを追加します。

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

注意

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