Aplicativos do Windows
Recolher sumário
Expandir sumário

Guia de início rápido: arrastando conteúdo

Applies to Windows only

É possível arrastar texto, imagens ou outros dados para reordená-los em uma GridView ou em uma ListView, ou então você pode arrastar itens para outros tipos de controles.

Em um aplicativo da Windows Store, é possível usar mouse, gesto de toque ou voz para arrastar itens para reordená-los em um GridView ou ListView, ou ainda pode arrastar um item de um único GridView ou ListView para outro controle XAML. Para arrastar de um GridView ou ListView, defina o atributo CanDragItems como True. Para habilitar um controle para que aceite itens arrastados, defina o atributo AllowDrop como True.

Você pode aplicar animações em operações de arrastar. Siga as mesmas diretrizes gerais fornecidas em Diretrizes para animações de arrastar, mesmo que esse tópico esteja escrito para JavaScript. O artigo Animando sua interface do usuário mostra como aplicar animações de arrastar em XAML.

Não é possível arrastar itens entre aplicativos separados, mas você pode usar as APIs de compartilhamento ou a Área de Transferência para transferir dados nesses cenários. Todas as APIs de transferência de dados compartilham alguns tipos comuns (que incluem a classe Windows::ApplicationModel::DataTransfer ::DataPackage e a enumeração Windows::ApplicationModel::DataTransfer ::StandardDataFormats). Em uma operação de arrastar, a classe DataPackage é usada para encapsular os dados que estão sendo transferidos, e a enumeração StandardDataFormats define os formatos para os quais DataPackage fornece métodos Set* especiais. Esses formatos incluem Text, Bitmap, Html, Rtf, Uri e coleções do objeto StorageItem. A classe DataPackageView fornece os métodos Get* assíncronos usados no manipulador de eventos Drop para recuperar os dados. Você também pode arrastar objetos definidos pelo usuário usando o método DataPackage::SetData e os métodos DataPackageView::GetDataAsync.

Para habilitar o arraste de itens em um GridView ou ListView

É muito simples habilitar o arraste de elementos em um GridView ou um ListView. Basta definir esses atributos no controle no XAML: AllowDrop="True" CanDragItems="True" CanReorderItems="True"

Etapas básicas de arrastar

Quaisquer que sejam os tipos de dados que você esteja transferindo, uma operação de arrastar entre controles envolve duas etapas básicas:

  1. Manipular o evento Windows::UI::Xaml::Controls::DragItemsStarting na origem em que o gesto de arrastar começa, que pode ser Windows::UI::Xaml::Controls::GridView ou Windows::UI::Xaml::Controls::ListView. O parâmetro DragItemsStartingEventArgs contém uma referência ao(s) item(ns) que está(ão) sendo arrastado(s). O parâmetro também contém uma propriedade Data que é o DataPackage que será repassado para o destino de soltura. No manipulador de eventos, obtenha os dados que deseja repassar da coleção DragItemsStartingEventArgs::Items, e use esses dados para popular a propriedade Data da maneira mais apropriada para o seu cenário.

  2. Manipular o evento Windows::UI::Xaml::Controls::Drop no destino de soltura. Recupere o objeto DataPackage que é repassado, chame GetView para obter sua propriedade DataPackageView e use os métodos Get* para acessar os dados armazenados anteriormente no evento DragItemsStarting. O destino de soltura pode ser qualquer controle XAML que permita o evento "Drop".

Eventos adicionais — DragEnter e DragLeave e DragOver — são úteis principalmente para criar animações ou outros efeitos visuais, mas não são essenciais para a operação básica de transferência de dados em si.

Para arrastar texto

No exemplo a seguir, pressuponha que a origem de arrastar seja um GridView que contém itens String e que DragItemsStarting_1 seja o manipulador de eventos para o evento DragItemsStarting disparado pelo GridView. Se a propriedade GridView:: SelectionMode for definida como Multiple, a coleção Items poderá conter mais de um elemento. Neste exemplo, pressuponha que SelectionMode esteja definido como Single, para que seja seguro pressupor que o item sendo arrastado está na posição 0.

Arrastar:


void DragDrop::DragText::DragTextGridView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{    
    auto mytxt = safe_cast<String^>(e->Items->GetAt(0));
    e->Data->SetText(mytxt);
}

Soltar:

O exemplo a seguir mostra como manipular o evento Drop. Pressuponha neste caso que o destino de soltura seja um elemento TextBlock XAML.


void DragDrop::DragText::DropTextHere_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
    using namespace concurrency;
    using namespace Windows::ApplicationModel::DataTransfer;

    DataPackageView^ dataView = e->Data->GetView();
    create_task(dataView->GetTextAsync())
    .then([this, sender](String^ txt)
    {
        TextBlock^ tb = safe_cast<TextBlock^>(sender);
        tb->Text = txt;
    });
}

Para arrastar bitmaps

Se um BitmapImage for obtido de um arquivo, use os métodos DataPackage::SetStorageItems e DataPackageView::GetStorageItemsAsync para arrastá-lo como um IStorageItem. Além disso, se for necessário criar um GridView ou ListView de objetos BitmapImage baseados em arquivo arrastáveis, a melhor abordagem será criar um objeto wrapper associável que contenha como propriedades públicas o BitmapImage e o StorageFile original, e talvez outras informações como atributos ou nome do arquivo. Como um objeto IStorageItem em si não é associável, ele não pode ser exibido facilmente em um GridView.

Importante  Apesar de ser possível usar a classe FileInformation para associar objetos de arquivo virtualizados a um controle XAML, os objetos virtualizados não são facilmente arrastáveis.

No exemplo a seguir, pressuponha que a origem de arrastar seja um ListView com dados associados a uma lista de objetos PhotoWrapper definidos pelo usuário. Cada PhotoWrapper contém um BitmapImage e o objeto StorageFile que foi obtido quando o arquivo foi aberto originariamente. O DataTemplate no ListView é associado à propriedade ImageFile.


    [Windows::UI::Xaml::Data::Bindable]
    public ref class PhotoWrapper sealed
    {
    public:
        property Windows::UI::Xaml::Media::Imaging::BitmapImage^ Thumbnail;
        property Windows::Storage::StorageFile^ ImageFile;
    };

Arrastar:

O seguinte manipulador de eventos DragItemsStarting mostra como criar uma lista de um ou mais objetos IStorageItem na operação Drag e como inseri-lo(s) no DataPackage.


void DragDrop::DragImage::ListView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{
    IVector<IStorageItem^>^ selectedFiles = ref new Vector<IStorageItem^>();
    for (unsigned int i = 0; i < e->Items->Size; i++)
    {
        PhotoWrapper^ wrapper = safe_cast<PhotoWrapper^>(e->Items->GetAt(i));
        selectedFiles->Append(wrapper->ImageFile);
    }

    e->Data->SetStorageItems(selectedFiles);
}

Soltar:

No evento Drop, obtenha a propriedade DataPackageView somente leitura e chame o método OpenReadAsync para recuperar o fluxo e criar o BitmapImage a partir dele. Depois que essa operação for concluída, defina a propriedade Source no controle Image e remova o objeto PhotoWrapper correspondente da lista de origem.


void DragDrop::DragImage::ListView_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
    DataPackageView^ dpView = e->Data->GetView();

    create_task(dpView->GetStorageItemsAsync())
    .then([this](IVectorView<IStorageItem^>^ images)
    {
        for (unsigned int i = 0; i < images->Size; i++)
        {
            create_task([images, i, this]()
            {
                // Get a stream from the file object.
                IStorageFile^ file = safe_cast<IStorageFile^>(images->GetAt(i));
                return file->OpenReadAsync();
            }).then([this](IRandomAccessStreamWithContentType^ s)
            {
                // Set the stream as the bitmap source
                BitmapImage^ bi = ref new BitmapImage();
                bi->SetSourceAsync(s);
                return bi;
            }).then([this](BitmapImage^ bi)
            {
                // Add the BitmapImage to the source list.
                // The update will be reflected in the ListView.
                m_targetImages->Append(bi);
            });
        }        
    });
}

Para arrastar objetos definidos pelo usuário

Você pode arrastar objetos personalizados inserindo-os no contêiner associativo DataPackage::Properties. Nesse caso, como DataPackage não tem conhecimento dos dados, especifique uma chave de cadeia de caracteres que descreva o formato dos dados. Em uma operação de arrastar, a cadeia de formato é particular ao aplicativo. Assim, você não precisa escolher um nome de entendimento universal. Basta fornecer essa mesma cadeia de caracteres quando recuperar os dados. Neste exemplo, a mesma chave é inserida para todos os itens, mas você também pode inserir uma chave individual para cada item.

No exemplo a seguir, imagine que temos uma classe associável City e queremos arrastar um ou mais objetos City de GridView para ListView.


    [Windows::UI::Xaml::Data::Bindable]
    public ref class City sealed
    {
    public:
        City(Platform::String^ name, int pop)
        {
            this->Name = name;
            this->Population = pop;
        }
        property Platform::String^ Name;
        property int Population;
    };

Arrastar:


void DragDrop::MainPage::GridView_DragItemsStarting_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::DragItemsStartingEventArgs^ e)
{
    for (auto item : e->Items)
    {    
        // If you want to drop only a subset of the dragged items,
        // then make each key unique.    
        e->Data->Properties->Insert("MyApp.MyCity", item);
    }
}

Soltar:

Na operação de soltar em C++, os itens são recuperados de DataPackage, reconvertidos em seu tipo original City e copiados para uma fonte de dados no destino de soltura.


void DragDrop::MainPage::ListViewDropTarget_Drop_1(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{    
    DataPackageView^ dpView = e->Data->GetView();
    for (auto prop : dpView->Properties)
    {
        auto city = safe_cast<City^>(prop->Value);
        m_dropTargetItems->Append(city);
    }  
}

 

 

Mostrar:
© 2017 Microsoft