Тема: Поддержка Drag & Drop в Silverlight 4
Поддержка Drag & Drop в Silverlight 4
оригинал: Silverlight 4's New Drag-and-Drop Support
Еще одна новая возможность в Silverlight 4, которая позволит создавать более привлекательные приложения – это поддержка буксировки файлов. В Silverlight 3 вам приходилось вызывать OpenFileDialog, чтобы пользователь мог выбрать нужные файлы на локальном диске и предоставить их в Silverlight приложение. В Silverlight 4 OpenFileDialog никуда не делся, но появилась альтернатива, позволяющая пользователям перетаскивать файлы из оболочки операционной системы в приложение Silverlight. Затем приложение может открывать эти файлы, точно также как это происходит при работе с OpenFileDialog.
Для демонстрации механизма приема файлов в Silverlight я сделал пример, который позволяет открывать файлы изображений через drag & drop. Вот как выглядит приложение, после того как я перетащил на него некоторые JPEG файлы:

При старте приложение регистрирует обработчик для события Drop, принадлежащее классу UIElement, благодаря чему элемент Grid становится способным принимать файлы:
// Register a handler for Drop events
LayoutRoot.Drop += new DragEventHandler(LayoutRoot_Drop);Когда один или несколько файлов брошены на элемент Grid, метод LayoutRoot_Drop добавляет соответствующие файлам объекты FileInfo в System.Collections.Generic.Queue:
// Queue the FileInfo objects representing dropped files
if (e.Data != null)
{
FileInfo[] files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
foreach (FileInfo fi in files)
{
_files.Enqueue(fi);
}
}Затем обработчик события CompositionTarget.Rendering извлекает из очереди объекты FileInfo и обрабатывает их по одному за раз (один объект FileInfo за одной событие CompositionTarget.Rendering), отправляя их в XAML в виде объектов Image взятых в рамку:
if (_files.Count != 0)
{
// Create a photo
FileInfo fi = _files.Dequeue();
CreatePhoto(fi);
}Причина использования CompositionTarger.Rendering в том, что изображения распаковываются и превращаются в объект Image в основном UI-потоке приложения. Обрабатывая один объект FileInfo и возвращая управление, обработчик события не задерживает выполнение основного потока, поэтому механизм построение изображения может отобразить добавленную фотографию.
Для поддержки drag & drop Silverlight 4 предусматривает четыре новых события в классе UIElement: DragEnter, DragOver, Drop и DragLeave. Таким образом, любой визуальный элемент может принимать файлы. В других приложениях не из семейства Silverlight вы можете воспользоваться передаваемым в эти события параметром IDataObject для определения типа перетаскиваемого файла. Однако в Silverlight вы можете обращаться к IDataObject только в обработчиках события Drop. Но это не мешает вам использовать остальные события для подсвечивания элемента-приемника файлов или для каких-то других вспомогательных действий в момент, когда курсор с файлом перемещается над элементом-приемником.
Еще одна деталь истории с drag & drop в новом свойстве UIElement.AllowDrop. Чтобы объект мог принимать файлы, этой свойство должно быть выставлено в true. Вот почему мой пример приложения объявляет LayoutRoot следующим образом:
<Grid x:Name="LayoutRoot" AllowDrop="True">Вы можете скачать исходники и покопаться в них. Успехов.