Поделиться через


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

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

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