数据和数据对象

更新:2011 年 4 月

在拖放操作中传输的数据存储在数据对象中。 概念上而言,数据对象包含一对或多对下列组件:

  • 一个包含实际数据的 Object

  • 一个对应的数据格式标识符。

数据本身可以包含作为基本 Object 表示的任何内容。 对应的数据格式是提供有关数据格式的提示的字符串或 Type。 数据对象支持承载多个“数据/数据格式”对;这样,一个数据对象即可提供多种格式的数据。

数据对象

所有数据对象都必须实现 IDataObject 接口,该接口提供以下标准方法集,以启用和便于数据传输。

方法

摘要

GetData

检索指定数据格式的数据对象。

GetDataPresent

查看是否具有指定格式的数据,或者数据是否可以转换为指定格式。

GetFormats

返回一个格式列表,此数据对象中的数据以这些格式存储,或可以转换为这些格式。

SetData

在此数据对象中存储指定的数据。

WPF 提供 DataObject 类中的 IDataObject 的基本实现。 对于许多常见数据传输方案,常用 DataObject 类已足够满足要求。

有几种预定义格式,如位图、CSV、文件、HTML、RTF、字符串、文本和音频。 有关随 WPF 提供的预定义数据格式的信息,请参见 DataFormats 类参考主题。

数据对象通常包括在提取数据时将以一种格式存储的数据自动转换为另一种格式的功能,此功能称为自动转换。 当查询数据对象中的可用数据格式时,可以通过调用 GetFormatsGetDataPresent 方法并将 autoConvert 参数指定为 false 来从本机数据格式中筛选可自动转换的数据格式。 当使用 SetData 方法将数据添加到数据对象中时,可以通过将 autoConvert 参数设置为 false 来禁止数据自动转换。

处理数据对象

本节介绍创建和处理数据对象的常见技术。

创建新数据对象

DataObject 类提供一些重载构造函数,以便于使用单一“数据/数据格式”对来填充新的 DataObject 实例。

下面的代码示例新建一个数据对象,并利用重载构造函数之一 DataObject(DataObject),使用一个字符串和指定的数据格式初始化该数据对象。 在这种情况下,数据格式由一个字符串指定;DataFormats 类提供一组预定义的类型字符串。 默认情况下允许存储数据的自动转换。

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

有关创建数据对象的更多代码示例,请参见如何:创建数据对象

存储多种格式的数据

一个数据对象能够存储多种格式的数据。 与只提供一种数据格式相比较,在一个数据对象中策略性地使用多种数据格式可以使该数据对象供更多种放置目标使用。 请注意,一般而言,拖动源一定不知道潜在放置目标可使用的数据格式。

下面的示例演示如何使用 SetData 方法将数据以多种格式添加到数据对象中。

                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)
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 重载获取一个字符串数组,该数组用于表示某数据对象中可用的所有数据格式(包括本机和自动转换的格式)。

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
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 方法检索数据。

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
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 两次会导致“数据/数据格式”在数据对象中出现两次。

修订记录

日期

修订记录

原因

2011 年 4 月

新增主题。

客户反馈