Inicio rápido: arrastrar contenido

Los usuarios pueden arrastrar texto, imágenes u otros datos para reordenarlos en una GridView o ListView, o pueden arrastrar elementos a otros tipos de controles.

En una aplicación de la Tienda Windows, puedes usar un mouse, un gesto de tocar o la voz para arrastrar elementos y reordenarlos en una GridView o ListView, o puedes arrastrar un elemento de una sola GridView o ListView a otro control XAML. Para arrastrar desde una GridView o ListView, establece el atributo CanDragItems en True. Para permitir que un control acepte elementos arrastrados, establece el atributo AllowDrop en True.

Puedes aplicar animaciones a las operaciones de arrastrar. Sigue las mismas directrices generales proporcionadas en Directrices para animaciones de arrastrar, aunque ese tema sea específico para JavaScript. El artículo Animación de la interfaz de usuario te muestra cómo aplicar animaciones de arrastrar en XAML.

No se admite arrastrar entre aplicaciones independientes, pero puedes usar las API de uso compartido o el Portapapeles para transferir datos en esos escenarios. Todas las API de transferencia de datos comparten algunos tipos, como la clase Windows::ApplicationModel::DataTransfer ::DataPackage y la enumeración Windows::ApplicationModel::DataTransfer ::StandardDataFormats. En una operación de arrastrar, la clase DataPackage se usa para encapsular los datos que se están transfiriendo y la enumeración StandardDataFormats define formatos para los que DataPackage proporciona métodos Set* especiales. Por ejemplo: Text, Bitmap, Html, Rtf, Uri y colecciones del objeto StorageItem. La clase DataPackageView proporciona métodos Get* asincrónicos en el controlador de eventos Drop para recuperar los datos. También puedes arrastrar objetos definidos por el usuario mediante el método DataPackage::SetData y los métodos DataPackageView::GetDataAsync.

Para permitir que se puedan arrastrar elementos en GridView o ListView

Permitir que se puedan arrastrar elementos de una GridView o ListView es algo trivial. Simplemente debes establecer estos atributos en el control en el XAML: AllowDrop="True" CanDragItems="True" CanReorderItems="True"

Pasos básicos para arrastrar

Independientemente del tipo de datos que estés transfiriendo, una operación de arrastrar entre controles tiene dos pasos básicos:

  1. Controla el evento Windows::UI::Xaml::Controls::DragItemsStarting en el origen donde comienza el gesto de arrastrar, que puede ser Windows::UI::Xaml::Controls::GridView o Windows::UI::Xaml::Controls::ListView. El parámetro DragItemsStartingEventArgs contiene una referencia al elemento o los elementos que se pueden arrastrar. El parámetro también contiene una propiedad Data que es el DataPackage que se pasará al destino de colocación. En el controlador de eventos, obtén los datos que quieras pasar de la colección DragItemsStartingEventArgs::Items y, a continuación, usa esos datos para rellenar la propiedad Data de la manera más adecuada para tu escenario.

  2. Controla el evento Windows::UI::Xaml::Controls::Drop en el destino de colocación. Recupera el objeto DataPackage que se pasa, llama a GetView para obtener su propiedad DataPackageView y usa sus métodos Get* para acceder a los datos que anteriormente almacenaste en el evento DragItemsStarting. Un destino de colocación puede ser cualquier control XAML que admita el evento "Drop".

Los eventos adicionales (DragEnter, DragLeave y DragOver) son principalmente útiles para crear animaciones u otros efectos visuales pero no son esenciales para la propia operación de transferencia de datos básica.

Para arrastrar texto

En el siguiente ejemplo, supongamos que el origen de arrastre es una GridView que contiene elementos String y que DragItemsStarting_1 es el controlador de eventos del evento DragItemsStarting activado por GridView. Si la propiedad GridView:: SelectionMode se establece en Multiple, la colección Items puede contener más de un elemento. En este ejemplo, supongamos que SelectionMode está establecido en Single, de modo que se puede suponer con seguridad que el elemento que se está arrastrando está en la posición 0.

Arrastrar:


private void DragTextGridView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
{
    var mytxt = e.Items[0] as String;
    if (mytxt != null)
    {
        e.Data.SetText(mytxt);
    }
}

Colocar:

El siguiente ejemplo muestra cómo controlar el evento Drop. Supongamos en este caso que el destino de colocación es un elemento TextBlock de XAML.


private async void DropTextHere_Drop_1(object sender, DragEventArgs e)
{
    var dataView = e.Data.GetView();
    var tb = sender as TextBlock;
    if (sender != null)
    {
        tb.Text = await dataView.GetTextAsync();
    }
}

Para arrastrar mapas de bits

Si se obtiene una BitmapImage de un archivo, usa los métodos DataPackage::SetStorageItems y DataPackageView::GetStorageItemsAsync para arrastrarla como una IStorageItem. Además, si debes crear una GridView o ListView de objetos BitmapImage basados en archivos que puedan arrastrarse, lo mejor es crear un objeto contenedor enlazable que contenga como propiedades públicas la BitmapImage y el StorageFile original, y quizás otra información como el nombre de archivo o atributos. Dado que un objeto IStorageItem en sí mismo no puede enlazarse, no se puede mostrar fácilmente en una GridView.

Importante  Aunque puedes usar la clase FileInformation para enlazar objetos de archivos virtualizados a un control XAML, los objetos virtualizados no pueden arrastrarse fácilmente.

En el siguiente ejemplo, supongamos que el origen de arrastre es una ListView enlazada a datos de una lista de objetos PhotoWrapper definidos por el usuario. Cada PhotoWrapper contiene una BitmapImage y el objeto StorageFile que se obtuvo cuando se abrió el archivo originalmente. La DataTemplate en la ListView se enlaza a la propiedad ImageFile.


    public sealed class PhotoWrapper
    {
        public BitmapImage Thumbnail { get; set; }
        public StorageFile ImageFile { get; set; }
    }

Arrastrar:

El siguiente controlador de eventos DragItemsStarting muestra cómo crear una lista de uno o más objetos IStorageItem en la operación Drag e insertarlos en el DataPackage.


        void ListView_DragItemsStarting_1(object sender, DragItemsStartingEventArgs e)
        {
            IList<IStorageItem> selectedFiles = new List<IStorageItem>();
            foreach (var item in e.Items)
            {
                var wrapper = item as PhotoWrapper;
                selectedFiles.Add(wrapper.ImageFile);
            }

            e.Data.SetStorageItems(selectedFiles);
        }

Colocar:

En el evento Drop, obtén la propiedad DataPackageView de solo lectura y llama al método OpenReadAsync para recuperar la secuencia y, a continuación, crea una BitmapImage a partir de ella. Una vez finalizada la operación, establece la propiedad Source en el control Image y, a continuación, quita el objeto PhotoWrapper correspondiente de la lista de origen.


        private async void ListView_Drop_1(object sender, DragEventArgs e)
        {
            var dpView = e.Data.GetView();
            var images = await dpView.GetStorageItemsAsync();

            foreach (var image in images)
            {
                // Get a stream from the file object.
                IStorageFile file = image as StorageFile;
                var randomStream = await file.OpenReadAsync();

                // Set the stream as the bitmap source
                BitmapImage bi = new BitmapImage();
                await bi.SetSourceAsync(randomStream);

                // Add the BitmapImage to the source list.
                // The update will be reflected in the ListView.
                m_targetImages.Add(bi);
            }
        }
  

Para arrastrar objetos definidos por el usuario

Puedes arrastrar objetos personalizados insertándolos en el contenedor asociativo DataPackage::Properties. En este caso, dado que DataPackage no tiene conocimiento de los datos, debes proporcionar una clave de cadena que describa el formato de datos. En una operación de arrastrar, la cadena de formato es privada en la aplicación. Por lo tanto, no es necesario que elijas un nombre que sea comprensible universalmente. Tan solo proporciona la misma cadena cuando recuperes los datos. En este ejemplo, se proporciona la misma clave para todos los elementos, pero también podrías proporcionar cada elemento con una clave individual.

En el siguiente ejemplo, supongamos que tenemos una clase City enlazable y que queremos arrastrar uno o más objetos City de una GridView a una ListView.


    public sealed class City
    {
        public City(String name, int pop)
        {
            this.Name = name;
            this.Population = pop;
        }
        public String Name { get; set; }
        public int Population { get; set; }
    }


Arrastrar:


void GridView_DragItemsStarting_1(Object sender, DragItemsStartingEventArgs e)
{
    foreach(var item in e.Items)
    {
        // If you want to drop only a subset of the dragged items,
        // then make each key unique. 
        e.Data.Properties.Add("MyApp.MyCity", item);
     }
}

Colocar:

En la operación de colocación en C++, los elementos se recuperan de DataPackage, se convierten de nuevo en su tipo original de City y se copian en el origen de datos para el destino de colocación.


void ListViewDropTarget_Drop_1(Object sender, DragEventArgs e)
{
    DataPackageView dpView = e.Data.GetView();
    foreach (var prop in dpView.Properties)
    {
        var city = prop.Value as City;
        m_dropTargetItems.Add(city);
    }
}

 

 

Mostrar:
© 2014 Microsoft