Arrastrar y colocar

La función de arrastrar y colocar es una manera intuitiva de transferir datos dentro de una aplicación o entre aplicaciones en el escritorio de Windows. La función de arrastrar y colocar permite al usuario transferir datos entre aplicaciones o dentro de una misma aplicación mediante un gesto estándar (mantener pulsado y desplazarse con el dedo o pulsar y desplazarse con el ratón o un lápiz).

API importantes: propiedad CanDrag, propiedad AllowDrop

El origen del arrastre, que es la aplicación o el área donde se desencadena el gesto de arrastrar, proporciona los datos que se van a transferir rellenando un objeto de paquete de datos que puede contener formatos de datos estándar, incluidos 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 ha realizado.

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. Inicialmente, el origen es el que proporciona estos comentarios visuales, pero los destinos pueden cambiarlos a medida que el puntero se mueve sobre ellos.

La función actual 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 clásicas de Windows, aunque este artículo se centra en la API de XAML de la función de arrastrar y colocar más actual. 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 sobre lo que tiene que hacer para habilitar la función de arrastrar y colocar en la aplicación:

  1. Para habilitar la función de arrastrar en un elemento, establezca su propiedad CanDrag en true.
  2. Cree el paquete de datos. El sistema controla automáticamente las imágenes y el texto, pero para otros tipos de contenido, deberá controlar los eventos DragStarting y DropCompleted y usarlos para construir su propio paquete de datos.
  3. Para habilitar la función de colocar, establezca la propiedad AllowDrop en true en todos los elementos que pueden recibir el contenido colocado.
  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 colocado.

Habilitar la función de arrastrar

Para habilitar la función de arrastrar 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 puedan arrastrar.

Sea 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 ningún otro trabajo para permitir la función de arrastrar, a menos que quiera personalizar la interfaz de usuario (de lo cual se trata más adelante en este artículo). La función de colocar 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 automáticamente. 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.

Habilitar la función de colocar

El marcado siguiente muestra cómo se puede usar la propiedad AllowDrop para especificar que un área de la aplicación es un destino de colocación válido para un elemento arrastrado (el área especificada no debe tener un fondo nulo, debe poder recibir la entrada del puntero y el elemento no se puede quitar en ningún lugar distinto del área especificada).

Nota:

Normalmente, un elemento de la interfaz de usuario tiene un fondo nulo de forma predeterminada. Si quieres que los usuarios puedan quitar un elemento en cualquier parte de la aplicación, el fondo de la aplicación no puede ser NULL (establecer Background="Transparent" si el fondo no debe estar visible).

<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 ha arrastrado un elemento sobre la aplicación, pero aún no lo ha colocado. En este controlador, tiene que especificar qué tipo de operaciones admite la aplicación mediante la propiedad AcceptedOperation. La operación copiar es la más habitual.

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

Procesamiento del evento Drop

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

Para facilitar las cosas, en el siguiente ejemplo supondremos que el usuario ha colocado una sola foto y accede a ella directamente. En realidad, los usuarios pueden colocar varios elementos de distintos formatos simultáneamente. La aplicación debe controlar esta posibilidad comprobando qué tipos de archivos se han colocado y cuántos hay, y procesando 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;
        }
    }
}

Personalización de la interfaz de usuario

El sistema proporciona una interfaz de usuario predeterminada para arrastrar y colocar. Sin embargo, también puede elegir personalizar varias partes de la interfaz de usuario estableciendo subtítulos y glifos personalizados, u optando por no mostrar una interfaz de usuario en absoluto. Para personalizar la interfaz de usuario, use 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 en un elemento que se puede arrastrar con la función táctil

Al usar la función táctil, arrastrar un UIElement y abrir su menú contextual comparte gestos táctiles similares; cada acción comienza con pulsar y sostener. Así es como el sistema anula la ambigüedad entre las dos acciones de los elementos de la aplicación que admiten ambas:

  • Si un usuario pulsa y sostiene un elemento y comienza a arrastrarlo en menos de 500 milisegundos, el elemento se arrastra y no aparece el menú contextual.
  • Si el usuario pulsa y sostiene el elemento, pero no lo arrastra en menos de 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 inicia la acción de arrastrar.

Designación de un elemento de un control ListView o GridView como carpeta

Puede especificar un control ListViewItem o GridViewItem como carpeta. Esto es especialmente útil para los escenarios TreeView y Explorador de archivos. Para ello, establezca explícitamente la propiedad AllowDrop en True en ese elemento.

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

Habilitar la reordenación de la función de arrastrar y colocar en ListViews

ListViews admite la reordenación basada en arrastrar, con una API muy similar a la API CanDrop que se describe en este artículo. Como mínimo, puede agregar las propiedades AllowDrop y CanReorderItems.

Consulte ListViewBase.CanReorderItems para más información.

Implementación de una función de arrastrar y colocar personalizada

La clase UIElement realiza la mayor parte del trabajo de implementación de la función de arrastrar y colocar automáticamente. Pero si lo desea, puede implementar su propia versión mediante las siguientes API.

Funcionalidad WinAppSDK API
Espacio de nombres Microsoft.UI.Input.DragDrop
UWP API
Espacio de nombres Windows.Applicationmodel.DataTransfer.DragDrop.Core
DragPrimitive DragOperation CoreDragOperation
Crea un paquete de datos DataPackage same
Envía la acción de arrastrar al shell DragOperation.StartAsync CoreDragOperation.StartAsync
Recibe la acción de colocar del shell DragDropManager.TargetRequested
ICoreDropOperationTarget
CoreDragDropManager.TargetRequested
ICoreDropOperationTarget

Consulte también