Arrastrar y colocar

Arrastrar y colocar es una manera intuitiva de transferir datos dentro de una aplicación o entre aplicaciones en Windows escritorio. Arrastrar y colocar permite al usuario transferir datos entre aplicaciones o dentro de una aplicación mediante un gesto estándar (mantener presionado y desplazarse con el dedo o presionar y desplazarse con un mouse o un lápiz óptico).

API importantes: propiedad CanDrag, propiedad AllowDrop

El origen de arrastre, que es la aplicación o el área donde se desencadena el gesto de arrastrar, proporciona los datos que se transferirán rellenando un objeto de paquete de datos que puede contener formatos de datos estándar, como texto, RTF, HTML, mapas de bits, elementos de almacenamiento o formatos de datos personalizados. El origen también indica el tipo de operaciones que admite: copiar, mover o vincular. Cuando se suelta el puntero, se produce la colocación. El destino de colocación, que es la aplicación o el área debajo del puntero, procesa el paquete de datos y devuelve el tipo de operación que realizó.

Durante la operación de arrastrar y colocar, la interfaz de usuario de arrastre proporciona una indicación visual del tipo de operación de arrastrar y colocar que tiene lugar. El origen proporciona inicialmente estos comentarios visuales, pero los destinos pueden cambiarlos a medida que el puntero se mueve sobre ellos.

La función moderna de arrastrar y colocar está disponible en todos los dispositivos que admiten UWP. Permite la transferencia de datos entre o dentro de cualquier tipo de aplicación, incluidas las aplicaciones de Windows clásicas, aunque este artículo se centra en la API XAML para arrastrar y colocar modernas. Una vez implementada, la opción para arrastrar y colocar elementos funciona perfectamente en todos los sentidos; por ejemplo, de una aplicación a otra, de una aplicación al escritorio y del escritorio a una aplicación.

Esta es una introducción a lo que debe hacer para habilitar la función de arrastrar y colocar en la aplicación:

  1. Habilite el arrastre en un elemento estableciendo su propiedad CanDrag en true.
  2. Compile el paquete de datos. El sistema controla las imágenes y el texto automáticamente, pero para otro contenido, deberá controlar los eventos DragStarting y DropCompleted y usarlos para construir su propio paquete de datos.
  3. Habilite la colocación estableciendo la propiedad AllowDrop en true en todos los elementos que pueden recibir contenido eliminado.
  4. Controle el evento DragOver para que el sistema sepa qué tipo de operaciones de arrastre puede recibir el elemento.
  5. Procese el evento Drop para recibir el contenido eliminado.

Habilitación del arrastre

Para habilitar el arrastre en un elemento, establezca su propiedad CanDrag en true. Esto hace que el elemento y los elementos que contiene, en el caso de colecciones como ListView, se pueden arrastrar.

Ser específico sobre lo que se puede arrastrar. Los usuarios no querrán arrastrar todo en la aplicación, solo determinados elementos, como imágenes o texto.

Aquí se muestra cómo establecer CanDrag.

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

No es necesario realizar ninguna otra acción para poder arrastrar elementos, a menos que quieras personalizar la interfaz de usuario (de la cual hablamos más adelante en este artículo). La opción para colocar elementos requiere algunos pasos más.

Construcción de un paquete de datos

En la mayoría de los casos, el sistema construirá un paquete de datos. El sistema controla automáticamente:

  • Imágenes
  • Texto

Para otro contenido, deberá controlar los eventos DragStarting y DropCompleted y usarlos para construir su propio DataPackage.

Habilitación de la colocación

En el siguiente marcado se muestra cómo establecer un área específica de la aplicación como un valor válido para la operación de colocar mediante AllowDrop en XAML. Si un usuario intenta colocar elementos en otro lugar, el sistema no se lo permitirá. Si quieres que los usuarios puedan colocar elementos en cualquier parte de la aplicación, establece todo el fondo como destino para colocar elementos.

<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>

Controlar el evento DragOver

El evento DragOver se desencadena cuando un usuario arrastra un elemento sobre la aplicación, pero aún no lo ha colocado. En este controlador, debes especificar qué tipo de operaciones admite la aplicación mediante el uso de la propiedad AcceptedOperation. La opción Copiar es la más común.

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

Procesar el evento Drop

El evento Drop se produce cuando el usuario suelta elementos en un área de colocación válida. Procésalos con la propiedad DataView.

Por motivos de simplicidad en el ejemplo siguiente, se supone que el usuario ha eliminado una sola foto y acceder a ella directamente. En realidad, los usuarios pueden colocar simultáneamente varios elementos de diferentes formatos. La aplicación debe controlar esta posibilidad comprobando qué tipos de archivos se han eliminado y cuántos hay, y procese cada uno en consecuencia. También debe considerar la posibilidad de notificar al usuario si está intentando hacer algo que la aplicación no admite.

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;
        }
    }
}

Personalizar la interfaz de usuario

El sistema proporciona una interfaz de usuario predeterminada para arrastrar y colocar elementos. Sin embargo, puedes personalizar diversas partes de la interfaz de usuario mediante el establecimiento de títulos y glifos personalizados o, directamente, optar por no mostrar ninguna interfaz de usuario. Para personalizar la interfaz de usuario, usa la propiedad 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
}

Abrir un menú contextual de un elemento que se pueda arrastrar con la función táctil

Cuando se usa la función táctil, las acciones de arrastrar una clase UIElement y abrir su menú contextual comparten gestos táctiles similares, ya que cada uno comienza con la operación de mantener presionado. A continuación te mostramos cómo el sistema elimina la ambigüedad entre las dos acciones para los elementos de la aplicación que admiten ambas:

  • Si un usuario mantiene presionado un elemento y comienza a arrastrar dentro de los 500 milisegundos, se arrastra el elemento y no se muestra el menú contextual.
  • Si el usuario mantiene presionado pero no arrastra dentro de los 500 milisegundos, se abre el menú contextual.
  • Una vez abierto el menú contextual, si el usuario intenta arrastrar el elemento (sin levantar el dedo), se descarta el menú contextual y se iniciará la operación de arrastrar.

Designar un elemento en una clase ListView o GridView como una carpeta

Puedes especificar una clase ListViewItem o GridViewItem como una carpeta. Esto es especialmente útil para escenarios de TreeView y Explorador de archivos. Para ello, establece explícitamente la propiedad AllowDrop en True en ese elemento.

El sistema mostrará automáticamente las animaciones adecuadas para colocar en una carpeta en vez de un elemento sin carpeta. El código de tu aplicación debe seguir controlando el evento Drop en el elemento de la carpeta (así como en el elemento sin carpeta) para actualizar el origen de datos y agregar el elemento a la carpeta de destino.

Habilitación de la reordenación de arrastrar y colocar en ListViews

ListViews admite la reordenación basada en arrastrar de forma completa, mediante una API muy similar a la API CanDrop que se describe en este artículo. Como mínimo, agregue las propiedades AllowDropy CanReorderItems .

Vea ListViewBase.CanReorderItems para obtener más información.

Implementación de arrastrar y colocar personalizados

La clase UIElement realiza la mayor parte del trabajo de implementación de arrastrar y colocar. Pero si lo desea, puede implementar su propia versión mediante las API de la Windows. Espacio de nombres ApplicationModel.DataTransfer.DragDrop.Core.

Funcionalidad WinRT API
Habilitación del arrastre CoreDragOperation
Creación de un paquete de datos DataPackage
Arrastre de mano al shell CoreDragOperation.StartAsync
Recepción de la caída del shell CoreDragDropManager
ICoreDropOperationTarget

Consulte también