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


Общие сведения о перетаскивании

В этом разделе представлен обзор поддержки перетаскивания в приложениях Windows Presentation Foundation (WPF). Перетаскиванием обычно называют метод передачи данных, который реализуется с помощью мыши (или другого указывающего устройства) для выбора одного или нескольких объектов и перетаскивания их в целевые объекты user interface (UI).

В этом разделе содержатся следующие подразделы.

  • Поддержка перетаскивания в WPF
  • Передача данных
  • События перетаскивания
  • Реализация перетаскивания
  • Пример перетаскивания
  • Связанные разделы

Поддержка перетаскивания в WPF

В операции перетаскивания обычно участвуют два элемента: источник перетаскивания, в котором находится перетаскиваемый объект, и объект-приемник, который получает перетаскиваемый объект. Источник и объект-приемник могут представлять собой элементы пользовательского интерфейса в одном или разных приложениях.

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

Конкретные действия, выполняемые во время операции перетаскивания, зависят от конкретного приложения и часто определяются контекстом. Например, при перетаскивании выделенных файлов из одной папки в другую на одном устройстве файлы перемещаются по умолчанию, тогда как при перетаскивании файлов из совместно используемого ресурса Universal Naming Convention (UNC) в локальную папку по умолчанию выполняется копирование.

Средства перетаскивания WPF являются гибкими и поддерживают возможность настройки в соответствии с целым рядом сценариев перетаскивания. Операции перетаскивания поддерживают работу с объектами в одном или разных приложениях. Также полностью поддерживается перетаскивание между приложениями WPF и другими приложениями Windows.

В системе WPF в операции перетаскивания могут принимать участие любые элементы UIElement и ContentElement. События и методы, необходимые для реализации операций перетаскивания, определены в классе DragDrop. Классы UIElement и ContentElement содержат псевдонимы для присоединенных событий DragDrop, чтобы эти события появлялись в списке членов класса при наследовании от базовых элементов UIElement и ContentElement. Обработчики событий, присоединенные к этим событиям, прикрепляются к базовому присоединенному событию DragDrop и получают тот же экземпляр данных события. Дополнительные сведения см. в разделе с описанием события UIElement.Drop.

Примечание о безопасностиПримечание по безопасности

Перетаскивание OLE пока не работает в зоне Интернета.

Передача данных

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

  • Исходный объект, который предоставляет данные.

  • Способ для временного хранения передаваемых данных.

  • Целевой объект, принимающий данные.

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

Источник перетаскивания инициирует операцию перетаскивания, вызывая метод DragDrop.DoDragDrop и передавая в него данные, предназначенные для передачи. При необходимости метод DoDragDrop автоматически заключит эти данные в объект DataObject. Для более эффективного управления форматом данных можно заключить данные в объект DataObject до их передачи в метод DoDragDrop. Объект-приемник отвечает за извлечение данных из объекта DataObject. Дополнительные сведения о работе с объектами данных см. в разделе Данные и объекты данных.

Источник и объект-приемник операции перетаскивания являются элементами пользовательского интерфейса, однако фактически передаваемые данные, как правило, не имеют визуального представления. Можно написать код для обеспечения визуального представления перетаскиваемых данных, как это сделано для перетаскивания файлов в проводнике. По умолчанию пользователь получает информацию о последствиях операции перетаскивания для данных — например, будут ли данные скопированы или перемещены — путем изменения курсора.

Последствия перетаскивания

Операции перетаскивания могут по-разному воздействовать на передаваемые данные. Например, данные можно скопировать или переместить. Для указания последствий операции перетаскивания можно использовать перечисление DragDropEffects, определяемое в WPF. В источнике перетаскивания можно указать те последствия, которые он разрешает в методе DoDragDrop. В объекте-приемнике для указания последствий, планируемых этим объектом, используется свойство Effects класса DragEventArgs. Когда объект-приемник указывает планируемое последствие в событии DragOver, эта информация передается обратно источнику перетаскивания в событии GiveFeedback. Используя эту информацию, источник перетаскивания сообщает пользователю о планируемом объектом-приемником последствии для данных. После перетаскивания данных объект-приемник указывает фактическое последствие перетаскивания в событии Drop. Эта информация передается обратно источнику перетаскивания в качестве возвращаемого значения метода DoDragDrop. Если объект-приемник возвращает последствие, которое отсутствует в списке allowedEffects источника перетаскивания, операция перетаскивания отменяется без фактической передачи данных.

Важно помнить, что в системе WPF значения DragDropEffects используются только для передачи информации между источником и объектом-приемником относительно последствий операции перетаскивания. Фактические последствия операции перетаскивания зависят от соответствующего кода приложения, написанного пользователем.

Например, объект-приемник может указать, что в результате перетаскивания данные будут перемещаться. Для перемещения данных их необходимо добавить в целевой элемент и удалить из исходного элемента. Исходный элемент может указать, что он разрешает перемещение данных, но если пользователь не предоставил код для удаления данных из исходного элемента, данные, в конечном результате, будут скопированы, а не перемещены.

События перетаскивания

Операции перетаскивания поддерживают модель управления с помощью событий. Источник и объект-приемник используют стандартный набор событий для обработки операций перетаскивания. В следующей таблице приводятся стандартные события перетаскивания. Это присоединенные события класса DragDrop. Дополнительные сведения о присоединенных событиях см. в разделе Общие сведения о вложенных событиях.

События источника

Событие

Сводка

[ E:System.Windows.DragDrop.GiveFeedback ]

Данное событие постоянно происходит в ходе операции перетаскивания; оно позволяет источнику перетаскивания обеспечивать обратную связь с пользователем. Эта обратная связь, как правило, предоставляется в форме изменения внешнего вида указателя мыши для указания последствий, разрешенных объектом-приемником. Это пузырьковое событие.

[ E:System.Windows.DragDrop.QueryContinueDrag ]

Это событие возникает при наличии изменений состояния клавиатуры или кнопок мыши во время операции перетаскивания и позволяет источнику отменить операцию перетаскивания в зависимости от состояния клавиш и кнопок. Это событие с восходящей маршрутизацией.

[ E:System.Windows.DragDrop.PreviewGiveFeedback ]

Туннельная версия GiveFeedback.

[ E:System.Windows.DragDrop.PreviewQueryContinueDrag ]

Версия QueryContinueDrag с нисходящей маршрутизацией.

События приемника

Событие

Сводка

[ E:System.Windows.DragDrop.DragEnter ]

Это событие возникает, когда объект перетаскивается в границы объекта-приемщика. Это пузырьковое событие.

[ E:System.Windows.DragDrop.DragLeave ]

Это событие возникает, когда объект перетаскивается за границы объекта-приемника. Это событие с восходящей маршрутизацией.

[ E:System.Windows.DragDrop.DragOver ]

Это событие постоянно возникает при перетаскивании (перемещении) объекта внутри границ объекта-приемника. Это событие с восходящей маршрутизацией.

[ E:System.Windows.DragDrop.Drop ]

Это событие возникает, когда объект отпускается на приемник. Это событие с восходящей маршрутизацией.

[ E:System.Windows.DragDrop.PreviewDragEnter ]

Версия DragEnter с нисходящей маршрутизацией.

[ E:System.Windows.DragDrop.PreviewDragLeave ]

Версия DragLeave с нисходящей маршрутизацией.

[ E:System.Windows.DragDrop.PreviewDragOver ]

Версия DragOver с нисходящей маршрутизацией.

[ E:System.Windows.DragDrop.PreviewDrop ]

Версия Drop с нисходящей маршрутизацией.

Для обработки событий перетаскивания для экземпляров объекта добавьте обработчики событий, перечисленных в предыдущих таблицах. Для обработки событий перетаскивания на уровне класса переопределите соответствующие виртуальные методы On*Event и On*PreviewEvent. Дополнительные сведения см. в разделе Обработка класса перенаправленных событий с помощью базовых классов элементов управления.

Реализация перетаскивания

Элемент пользовательского интерфейса может быть источником перетаскивания, объектом-приемником или обоими этими объектами. Для реализации базовой функциональности перетаскивания необходимо написать код для инициирования операции перетаскивания и обработки перетаскиваемых данных. Можно расширить возможности перетаскивания за счет обработки дополнительных событий перетаскивания.

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

  • Определите элемент, который будет источником перетаскивания. Источником перетаскивания может быть элемент UIElement или ContentElement.

  • Создайте обработчик событий в источнике перетаскивания, который будет инициировать операцию перетаскивания. Для инициирования, как правило, используется событие MouseMove.

  • Для инициирования операции перетаскивания вызовите метод DoDragDrop в обработчике событий источника перетаскивания. При вызове метода DoDragDrop необходимо указать источник перетаскивания, передаваемые данные и разрешенные последствия.

  • Определите элемент, который будет объектом-приемником. Объектом-приемником может быть элемент UIElement или ContentElement.

  • Задайте значение true для свойства AllowDrop объекта-приемника.

  • Создайте обработчик событий Drop в объекте-приемнике для обработки перетаскиваемых данных.

  • В обработчике событий Drop извлеките данные из объекта DragEventArgs с помощью методов GetDataPresent и GetData.

  • Эти данные используются в обработчике событий Drop для выполнения требуемой операции перетаскивания.

Реализацию перетаскивания можно расширить за счет создания пользовательского объекта DataObject и обработки дополнительных событий источника перетаскивания и объекта-приемника, как показано с следующих задачах.

  • Чтобы передавать пользовательские данные или несколько элементов данных, создайте объект DataObject, передаваемый в метод DoDragDrop.

  • Для выполнения дополнительных действий в процессе перетаскивания обработайте события DragEnter, DragEnter и DragEnter в объекте-приемнике.

  • Для изменения внешнего вида указателя мыши обработайте событие GiveFeedback в источнике перетаскивания.

  • Для изменения способа отмены операции перетаскивания обработайте событие QueryContinueDrag в источнике перетаскивания.

Пример перетаскивания

В этом разделе описывается реализация перетаскивания для элемента Ellipse. Элемент Ellipse является одновременно источником перетаскивания и объектом-приемником. Передаваемые данные — строковое представление свойства Fill эллипса. В следующем коде XAML показан элемент Ellipse и обрабатываемые им связанные события перетаскивания. Полное описание шагов по реализации перетаскивания см. в разделе Пошаговое руководство. Включение перетаскивания для пользовательского элемента управления.

Включение элемента в качестве источника перетаскивания

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

  • Определение момента начала перетаскивания.

  • Инициирование операции перетаскивания.

  • Определение передаваемых данных.

  • Определение разрешенных последствий операции перетаскивания для передаваемых данных.

Источник перетаскивания может также обеспечивать обратную связь с пользователем относительно разрешенных действий (перемещение, копирование или отсутствие разрешенных действий) и отменять операции перетаскивания в зависимости от дополнительных данных, введенных пользователем, например при нажатии клавиши ESC в процессе перетаскивания.

Момент начала перетаскивания определяется приложением, после чего инициируется операция перетаскивания путем вызова метода DoDragDrop. Момент начала, как правило, совпадает с событием MouseMove над перетаскиваемым элементом при нажатой кнопки мыши. В следующем примере показано инициирование операции перетаскивания из обработчика событий MouseMove элемента Ellipse, чтобы сделать этот элемент источником перетаскивания. Передаваемые данные — строковое представление свойства Fill эллипса.

Для инициирования операции перетаскивания вызовите метод DoDragDrop в обработчике событий MouseMove. Метод DoDragDrop принимает три параметра.

  • dragSource — ссылка на объект зависимости, который является источником передаваемых данных; это, как правило, источник события MouseMove.

  • data — объект, содержащий передаваемые данные, заключенные в объект DataObject.

  • allowedEffects — одно из значений перечисления DragDropEffects, которое определяет разрешенные последствия операции перетаскивания.

В параметре data можно передавать любые сериализуемые объекты. Если данные еще не заключены в объект DataObject, они будут автоматически заключены в новый объект DataObject. Для передачи нескольких элементов данных необходимо самостоятельно создать объект DataObject и передать его в метод DoDragDrop. Дополнительные сведения см. в разделе Данные и объекты данных.

Параметр allowedEffects используется для указания действий, которые источник перетаскивания разрешает объекту-приемнику выполнять с передаваемыми данными. Наиболее распространенными значениями для источника перетаскивания являются Copy, Move и All.

ПримечаниеПримечание

Объект-приемник также может указать последствия, которые он планирует реализовать в ответ на перетаскивание данных.Например, если объекту-приемнику не удается распознать тип перетаскиваемых данных, он может отвергнуть данные, задав для их разрешенных последствий значение None.Обычно это осуществляется в обработчике событий DragOver объекта-приемника.

Источник перетаскивания может также обрабатывать события GiveFeedback и QueryContinueDrag. У этих событий имеются обработчики по умолчанию, которые используются, если события не помечены как обработанные. Данные события, как правило, пропускаются; исключение составляют ситуации, когда необходимо изменить поведение этих событий по умолчанию.

Событие GiveFeedback возникает постоянно в процессе перетаскивания источника. Обработчик этого события по умолчанию проверяет, находится ли источник перетаскивания над допустимым объектом-приемником. В случае положительного ответа он проверяет последствия, разрешенные объектом-приемником. Затем обработчик предоставляет конечному пользователю сведения относительно разрешенных последствий перетаскивания. Это, обычно, выполняется с помощью изменения курсора мыши на курсор копирования, перетаскивания или запрета каких-либо действий. Данное событие следует обрабатывать, только если необходимо использовать пользовательские курсоры для обеспечения обратной связи с пользователем. При обработке этого события следует пометить его как обработанное; в противном случае пользовательский обработчик будет переопределен обработчиком по умолчанию.

Событие QueryContinueDrag возникает постоянно в процессе перетаскивания источника. Данное событие можно обработать, чтобы определить действие, которое завершает операцию перетаскивания, на основе состояния клавиш ESC, SHIFT, CTRL и ALT, а также состояния кнопок мыши. Обработчик данного события по умолчанию отменяет операцию перетаскивания при нажатии клавиши ESC и сбрасывает данные при отпускании кнопки мыши.

Предупреждающее замечаниеВнимание

Эти события происходят постоянно в процессе операции перетаскивания.Поэтому следует избегать выполнения ресурсоемких задач в обработчиках событий.Например, используйте кэшированный курсор вместо создания нового курсора при каждом возникновении события GiveFeedback.

Включение элемента в качестве объекта-приемника

Объект, являющийся объектом-приемником, отвечает за выполнение следующих задач.

  • Указание на допустимость объекта-приемника.

  • Реагирование на источник перетаскивания, когда его перетаскивают над объектом-приемником.

  • Проверка допустимости формата передаваемых данных.

  • Обработка перетащенных данных.

Чтобы указать элемент в качестве объекта-приемника, необходимо задать для его свойства AllowDrop значение true. После этого для данного элемента будут возникать события объекта-приемника, которые можно обрабатывать. В процессе операции перетаскивания в объекте-приемнике возникает следующая последовательность событий.

  1. [ E:System.Windows.DragDrop.DragEnter ]

  2. [ E:System.Windows.DragDrop.DragOver ]

  3. DragLeave или Drop

Событие DragEnter возникает, когда перетаскиваемые данные пересекают границу объекта-приемника. Данное событие, как правило, обрабатывается для предварительного просмотра последствий операции перетаскивания, если это поддерживается приложением. Не следует задавать свойство DragEventArgs.Effects в событии DragEnter, поскольку оно будет переопределено событием DragOver.

В следующем примере показан обработчик событий DragEnter для элемента Ellipse. В этом коде реализуется предварительный просмотр последствий операции перетаскивания путем сохранения текущей кисти Fill. Затем в нем используется метод GetDataPresent, чтобы проверить, содержит ли перетаскиваемый над эллипсом объект DataObject строковые данные, которые можно преобразовать в объект Brush. При наличии таких данных они извлекаются с помощью метода GetData. После этого они преобразуются в Brush и применяются к эллипсу. Изменения отменяются в обработчике событий DragLeave. Если данные невозможно преобразовать в объект Brush, никакие действия не выполняются.

Событие DragOver постоянно возникает при перетаскивании данных над объектом-приемником. Это событие сопоставляется с событием GiveFeedback источника данных. Чтобы проверить, может ли объект-приемник обработать формат передаваемых данных, в обработчике событий DragOver, как правило, используются методы GetDataPresent и GetData. Можно также проверить, нажата ли одна из клавиш-модификаторов, которые обычно указывают, какое действие намеревается выполнить пользователь — копирование или перемещение. После выполнения всех этих проверок задается свойство DragEventArgs.Effects, чтобы уведомить источник перетаскивания о последствии, которое перетаскивание будет иметь для данных. Источник перетаскивания получает эту информацию из аргументов события GiveFeedback; затем он может задать соответствующий курсор, чтобы предоставить необходимые сведения пользователю.

В следующем примере показан обработчик событий DragOver для элемента Ellipse. В этом коде проверяется, содержит ли перетаскиваемый над эллипсом объект DataObject строковые данные, которые можно преобразовать в объект Brush. При положительном результате проверки свойству DragEventArgs.Effects задается значение Copy. Это указывает источнику перетаскивания, что данные можно скопировать в эллипс. Если данные невозможно преобразовать в объект Brush, свойству DragEventArgs.Effects задается значение None. Это указывает источнику перетаскивания, что эллипс не является допустимым объектом-приемником для данных.

Событие DragLeave возникает, когда перетаскиваемые данные выходят за границу объекта-приемника без сбрасывания. Это событие обрабатывается для отмены всех действий, выполненных в обработчике событий DragEnter.

В следующем примере показан обработчик событий DragLeave для элемента Ellipse. В этом коде отменяется предварительный просмотр, выполненный в обработчике событий DragEnter путем применения объекта Brush к эллипсу.

Событие Drop возникают, когда данные сбрасываются над объектом-приемником; по умолчанию это происходит при отпускании кнопки мыши. Для извлечения передаваемых данных из объекта DataObject и их обработки в соответствии с требованиями приложения в обработчике событий Drop используется метод GetData. Событие Drop завершает операцию перетаскивания.

В следующем примере показан обработчик событий Drop для элемента Ellipse. Этот код, в котором применяются последствия операции перетаскивания, аналогичен коду обработчика событий DragEnter. В нем проверяется, содержит ли перетаскиваемый над эллипсом объект DataObject строковые данные, которые можно преобразовать в объект Brush. При наличии таких данных объект Brush применяется к эллипсу. Если данные невозможно преобразовать в объект Brush, никакие действия не выполняются.

См. также

Ссылки

Clipboard

Другие ресурсы

Пошаговое руководство. Включение перетаскивания для пользовательского элемента управления

Разделы Руководства по операциям перетаскивания

Перетаскивание

Журнал изменений

Дата

Журнал

Причина

Апрель 2011

Обновлен раздел.

Обратная связь от клиента.