Данные и объекты данных

Данные, которые передаются в ходе операции перетаскивания, хранятся в объекте данных. По сути, объект данных состоит из одной или нескольких следующих пар:

  • Объект Object, который содержит фактические данные.

  • Соответствующий идентификатор формата данных.

Сами данные могут состоять из любых элементов, которые можно представить в виде базового Object. Соответствующий формат данных представляет собой строку или Type, которые содержат указание на формат содержащихся в них данные. Объекты данных поддерживают размещение нескольких пар «данные-формат данных». Это позволяет одному объекту данных предоставлять данные в нескольких форматах.

Объекты данных

Все объекты данных должны реализовать интерфейс IDataObject, который предоставляет следующий стандартный набор методов, обеспечивающих и упрощающих передачу данных.

Метод Итоги
GetData Извлекает объект данных в указанном формате данных.
GetDataPresent Проверяет, доступны ли данные в или могут быть преобразованы в указанный формат.
GetFormats Возвращает список форматов, в которые хранятся данные в этом объекте данных или в которые можно преобразовать.
SetData Сохраняет указанные данные в этом объекте данных.

WPF предоставляет базовую реализацию IDataObject в классе DataObject. Класса DataObject достаточно для многих распространенных сценариев передачи данных.

Существует несколько предварительно определенных форматов, таких как растровое изображение, CSV, файл, HTML, RTF, строка, текст и аудиофайл. Сведения о предварительно определенных форматах данных, предоставляемых WPF, см. в справочном разделе для класса DataFormats.

Объекты данных обычно включают средство для автоматического преобразования данных, хранящихся в одном формате, в другой формат во время извлечения данных; такое средство называется автоматическим преобразованием. При запросе к форматам данных, доступным в объекте данных, автоматически преобразуемые форматы данных можно отфильтровать от собственных форматов данных путем вызова метода GetFormats(Boolean) или GetDataPresent(String, Boolean) и указания для параметра autoConvert значения false. При добавлении данных в объект данных с помощью метода SetData(String, Object, Boolean) автоматическое преобразование данных можно запретить, задав для параметра autoConvert значение false.

Работа с объектами данных

В этом разделе описываются распространенные приемы для создания и работы с объектами данных.

Создание объектов данных

Класс DataObject предоставляет несколько перегруженных конструкторов, которые упрощают заполнение нового экземпляра DataObject с одной парой «данные-формат данных».

Приведенный ниже пример кода создает новый объект данных и использует один из перегруженных конструкторов DataObject(DataObject(String, Object)) для инициализации объекта данных со строкой и заданным форматом данных. В этом случае формат данных задается строкой; а класс 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)

Дополнительные примеры кода, создающего объект данных, см. в разделе Создание объекта данных.

Хранение данных в нескольких форматах

Один объект данных может хранить данные в нескольких форматах. Стратегическое использование нескольких форматов данных в одном объекте данных потенциально делает объект данных доступным для потребления более широким спектром мест удаления, чем в случае, когда можно представить только один формат данных. Обратите внимание, что как правило, источник перетаскивания не должен зависеть от форматов данных, используемых потенциальными местами переноса.

В следующем примере показано, как использовать метод 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)

Запрос объекта данных для доступных форматов

Поскольку один объект данных может содержать произвольное количество форматов данных, объекты данных включают средства для получения списка доступных форматов данных.

В следующем примере кода используется перегрузка 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 можно использовать для проверки наличия определенного формата данных. 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 дважды для одних и тех же данных и формата данных приводит к тому, что данные и формат данных дважды добавляются в объект данных.