Общие сведения о перетаскивании
Обновлен: Ноябрь 2007
В этом разделе представлен обзор поддержки перетаскивания в приложениях Windows Presentation Foundation (WPF). Перетаскиванием обычно называют метод взаимодействия с пользовательский интерфейс, который реализуется с помощью мыши (или других указывающих устройств) для выбора одного или нескольких объектов и перетаскивания их в целевые объекты пользовательского интерфейса.
В этом разделе содержатся следующие подразделы.
- Поддержка перетаскивания в WPF
- Данные и объекты данных
- События перетаскивания
- Работа с объектами данных
- Связанные разделы
Поддержка перетаскивания в WPF
В операции перетаскивания обычно участвуют два элемента: источник перетаскивания, в котором находится перетаскиваемый объект, и объект-приемник, который получает перетаскиваемый объект. Источник и объект-приемник могут находиться в одном или разных приложениях.
Тип и количество объектов, которыми можно управлять с помощью перетаскивания, являются произвольными. Файл или несколько файлов или папок и выбранное содержимое являются наиболее распространенными объектами операции перетаскивания. Конкретные действия, выполняемые во время операции перетаскивания, зависят от конкретного приложения и часто определяются контекстом. Например, при перетаскивании выделенных файлов из одной папки в другую на одном устройстве файлы перемещаются по умолчанию, тогда как при перетаскивании файлов из совместно используемого ресурса формат UNC (Universal Naming Convention) в локальную папку по умолчанию выполняется копирование. Средства перетаскивания WPF являются гибкими и поддерживают возможность настроек для различных сценариев перетаскивания. Перетаскивание поддерживает управление объектами в одном приложении или в различных приложениях. Перетаскивание между приложениями WPF и другими приложениями Windows также полностью поддерживается. Перетаскивание попадает в общую категорию средств передачи данных. Кроме перетаскивания передача данных также включает использование системного буфера обмена для операций копирования и вставки.
Примечание безопасности: перетаскивание OLE пока не работает в зоне Интернет.
Данные и объекты данных
Данные, которые передаются как часть операции перетаскивания, хранятся в объекте данных. Концептуально объект данных состоит из одной или нескольких пар:
Object с фактическими данными и
соответствующего идентификатора формата данных.
Сами данные могут состоять из всего, что может быть представлено как базовый Object. Соответствующий формат данных является строкой или Type, который предоставляет подсказку, в каком формате представлены данные. Объекты данных поддерживают размещение нескольких пар данных (форматов данных); это позволяет одному объекту данных предоставлять данные в нескольких форматах.
Все объекты данных должны реализовывать интерфейс IDataObject, предоставляющий следующий стандартный набор методов для включения и упрощения передачи данных.
Метод |
Сводка |
---|---|
Извлекает объект данных в указанном формате данных. |
|
Проверяет, доступны ли данные в указанном формате, или возможность их преобразования в указанный формат. |
|
Возвращает список форматов, в которых данные хранятся в этом объекте данных или в которые их можно преобразовать. |
|
Сохраняет указанные данные в объекте данных. |
WPF предоставляет основную реализацию IDataObject в классе DataObject. Основной класс DataObject является достаточным для многих распространенных сценариев передачи данных.
Сведения о предопределенных форматах данных, предоставляемых WPF, см. в разделе с описанием класса DataFormats.
Данные объекты обычно включают средства для автоматического преобразования данных, хранящихся в одном формате, в другой формат во время извлечения данных; их обычно называют средствами автоматического преобразования.
При запросе форматов данных, доступных в объекте данных, автоматически преобразуемые форматы данных могут быть отфильтрованы от внутреннего формата данных с помощью метода GetFormats(Boolean) или GetDataPresent(String, Boolean) и задания для параметра autoConvert значения false. При добавлении данных к объекту данных с помощью метода SetData(String, Object, Boolean) автоматическое преобразование данных может быть запрещено с помощью задания для параметра autoConvert значения false.
События перетаскивания
Операции перетаскивания поддерживают модель управления с помощью событий. Источник и объект-приемник используют стандартный набор событий для обработки операций перетаскивания. В следующей таблице приводятся стандартные события перетаскивания.
События источника
Событие |
Сводка |
---|---|
Это событие возникает в начале операции перетаскивания и позволяет приемнику отправить информацию обратной связи источнику. Она часто используется источником перетаскивания для динамического изменения внешнего вида указателя мыши для предоставления пользователю обратной связи. Это пузырьковое событие. |
|
Это событие возникает при наличии изменений состояния клавиатуры или кнопок мыши во время операции перетаскивания и позволяет источнику отменить операцию перетаскивания в зависимости от состояния клавиш и кнопок. Это пузырьковое событие. |
|
Туннельная версия GiveFeedback. |
|
Туннельная версия QueryContinueDrag. |
События приемника
Событие |
Сводка |
---|---|
Это событие возникает, когда объект перетаскивается в границы объекта-приемщика. Это пузырьковое событие. |
|
Это событие возникает, когда объект перетаскивается за границы объекта-приемника. Это пузырьковое событие. |
|
Это событие возникает, когда объект перетаскивается (перемещается) внутри границы объекта-приемщика. Это пузырьковое событие. |
|
Это событие возникает, когда объект отпускается на приемник. Это пузырьковое событие. |
|
Туннельная версия DragEnter. |
|
Туннельная версия DragLeave. |
|
Туннельная версия DragOver. |
|
Туннельная версия Drop. |
Работа с объектами данных
В этом разделе описаны общие методы создания и работы с объектами данных.
Использование конструктора DataObject
Класс DataObject предоставляет несколько перегруженных конструкторов, облегчающих заполнение нового экземпляра DataObject парами данных (форматами данных).
В следующем примере создается новый объект данных и используется один из перегруженных конструкторов (DataObject(String, Object)) для инициализации объекта данных со строкой и заданным форматом данных. В этом случае формат данных определяется строкой. Класс DataFormats предоставляет набор строк предопределенных типов. Автоматическое преобразование сохраненных данных по умолчанию разрешено.
string stringData = "Some string data to store...";
string dataFormat = DataFormats.UnicodeText;
DataObject dataObject = 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);
Запрос к объекту данных для получения доступных форматов
Поскольку один объект данных может содержать произвольное число форматов данных, объекты данных включают средства для получения списка доступных форматов данных.
В следующем примере кода используется перегрузка 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(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[];
}
Дополнительные примеры кода, которые извлекают данные из объекта данных, см. в разделе Практическое руководство. Получение данных в определенном формате данных.
Удаление данных из объекта данных
Данные не могут быть удалены напрямую из объекта данных. Для эффективного удаления данных из объекта данных рекомендуется выполнить следующие действия:
Создайте новый объект данных, который будет содержать только данные, которые требуется сохранить.
Скопируйте необходимые данные из старых объектов данных в новый объект данных (с помощью команды «Копировать»). Чтобы скопировать данные, следует использовать один из методов GetData для извлечения Object, содержащего фрагмент данных, и один из методов SetData для добавления данных в новый объект данных.
Замените старый объект данных новым.
Примечание. |
---|
Методы SetData только добавляют данные к объекту данных. Они не заменяют данные даже при их совпадении с данными и форматом данных в предыдущем вызове. Вызов SetData дважды для одних и тех же данных и форматов данных приведет к отображению данных и формата данных в объекте дважды. |