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

Перетаскивание — это интуитивно понятный способ передачи данных в приложении или между приложениями на рабочем столе Windows. Перетаскивание позволяет пользователю передавать данные между приложениями или в приложении с помощью стандартного жеста (нажатие и сдвига с помощью пальца или нажатия мыши или сдвига с помощью мыши или пера).

Важные API: свойство CanDrag, свойство AllowDrop

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

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

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

Ниже приведены общие сведения о том, что необходимо сделать, чтобы включить перетаскивание в приложении:

  1. Включите перетаскивание элемента, задав для свойства CanDrag значение true.
  2. Создайте пакет данных. Система автоматически обрабатывает изображения и текст, но для другого содержимого необходимо обрабатывать события DragStarting и DropCompleted и использовать их для создания собственного пакета данных.
  3. Включите удаление, задав свойству AllowDrop значение true для всех элементов, которые могут получать удаленное содержимое.
  4. Обработайте событие DragOver , чтобы система знала, какой тип операций перетаскивания может получать элемент.
  5. Обработайте событие Drop , чтобы получить удаленное содержимое.

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

Чтобы включить перетаскивание элемента, задайте для свойства CanDrag значение true. Это делает элемент (и элементы, которые он содержит, в случае коллекций, таких как ListView), перетаскиваемыми.

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

Вот как задать CanDrag.

<Image x:Name="Image" CanDrag="True" Margin="10,292,10,0" Height="338"></Image>

Вам не нужно выполнять другие действия, чтобы разрешить перетаскивание, если вы не хотите настроить пользовательский интерфейс (который рассматривается далее в этой статье). Для удаления требуется несколько дополнительных шагов.

Создание пакета данных

В большинстве случаев система создаст пакет данных для вас. Система автоматически обрабатывает:

  • изображения;
  • Текст

Для другого содержимого необходимо обрабатывать события DragStarting и DropCompleted и использовать их для создания собственного dataPackage.

Включение удаления

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

<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
      Background="LightBlue" Margin="10,10,10,353">
    <TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>

Обработка события DragOver

Событие DragOver запускается, когда пользователь перетащил элемент по приложению, но еще не удалял его. В этом обработчике необходимо указать, какие операции поддерживает приложение с помощью свойства AcceptedOperation. Копирование является наиболее распространенным.

private void Grid_DragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
}

Обработка события Drop

Событие drop возникает, когда пользователь освобождает элементы в допустимой области удаления. Обработайте их с помощью свойства DataView .

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

private async void Grid_Drop(object sender, DragEventArgs e)
{
    if (e.DataView.Contains(StandardDataFormats.StorageItems))
    {
        var items = await e.DataView.GetStorageItemsAsync();
        if (items.Count > 0)
        {
            var storageFile = items[0] as StorageFile;
            var bitmapImage = new BitmapImage();
            bitmapImage.SetSource(await storageFile.OpenAsync(FileAccessMode.Read));
            // Set the image on the main page to the dropped image
            Image.Source = bitmapImage;
        }
    }
}

Настройка пользовательского интерфейса

Система предоставляет пользовательский интерфейс по умолчанию для перетаскивания и перетаскивания. Однако вы также можете настроить различные части пользовательского интерфейса, задав пользовательские подпись и глифы или не отображая пользовательский интерфейс вообще. Чтобы настроить пользовательский интерфейс, используйте свойство DragEventArgs.DragUIOverride .

private void Grid_DragOverCustomized(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.Copy;
    e.DragUIOverride.Caption = "Custom text here"; // Sets custom UI text
    // Sets a custom glyph
    e.DragUIOverride.SetContentFromBitmapImage(
        new BitmapImage(
            new Uri("ms-appx:///Assets/CustomImage.png", UriKind.RelativeOrAbsolute)));
    e.DragUIOverride.IsCaptionVisible = true; // Sets if the caption is visible
    e.DragUIOverride.IsContentVisible = true; // Sets if the dragged content is visible
    e.DragUIOverride.IsGlyphVisible = true; // Sets if the glyph is visibile
}

Открытие контекстного меню в элементе, который можно перетащить с помощью сенсорного ввода

При использовании сенсорного ввода перетаскивание UIElement и открытие контекстного меню совместно используют аналогичные жесты касания. Каждое из них начинается с нажатия и удержания. Вот как система диамбигирует между двумя действиями для элементов в приложении, которые поддерживают оба:

  • Если пользователь нажимает и держит элемент и начинает перетаскивать его в пределах 500 миллисекунд, элемент перетаскивается, а контекстное меню не отображается.
  • Если пользователь нажимает и удерживает, но не перетаскивает в пределах 500 миллисекунд, откроется контекстное меню.
  • После открытия контекстного меню, если пользователь пытается перетащить элемент (не поднимая пальцем), контекстное меню закрывается, а перетаскивание начнется.

Назначение элемента в ListView или GridView в качестве папки

Вы можете указать ListViewItem или GridViewItem в качестве папки. Это особенно полезно для сценариев TreeView и проводник. Для этого явно задайте для свойства AllowDrop значение True для этого элемента.

Система автоматически будет отображать соответствующие анимации для удаления в папку и элемента, отличного от папки. Код приложения должен продолжать обрабатывать событие Drop в элементе папки (а также в элементе, отличном от папки), чтобы обновить источник данных и добавить удаленный элемент в целевую папку.

Включение переупорядочения перетаскивания в ListViews

Функция ListViewподдерживает переупорядочение на основе перетаскивания из поля, используя API, очень похожий на API CanDrop , описанный в этой статье. Как минимум, можно добавить свойства AllowDrop и CanReorderItems .

Дополнительные сведения см. в listViewBase.CanReorderItems.

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

Класс UIElement выполняет большую часть работы по реализации перетаскивания. Но если вы хотите, вы можете реализовать собственную версию с помощью приведенных ниже API.

Функция Пространство имен WinAppSDK API
Microsoft.UI.Input.DragDrop
UWP API
Пространство имен Windows.Applicationmodel.DataTransfer.DragDrop.Core
DragPrimitive Перетаскивание CoreDragOperation
Создание пакета данных Datapackage —||—
Передача перетаскивания в оболочку DragOperation.StartAsync CoreDragOperation.StartAsync
Получение удаления из оболочки DragDropManager.TargetRequested
ICoreDropOperationTarget
CoreDragDropManager.TargetRequested
ICoreDropOperationTarget

См. также