Compartilhar via


Reconhecer um gesto de arrastar e soltar

Um reconhecimento de gestos de arrastar e soltar da interface do usuário de aplicativo multiplataforma do .NET (.NET MAUI) permite que os itens e seus pacotes de dados associados sejam arrastados de um local na tela para outro local usando um gesto contínuo. Arrastar e soltar pode ocorrer em um único aplicativo ou pode começar em um aplicativo e terminar em outro.

A origem do gesto de arrastar, que é o elemento no qual o gesto de arrastar é iniciado, pode fornecer dados a serem transferidos preenchendo um objeto de pacote de dados. Quando a origem do gesto de arrastar é liberada, o item é solto. O destino do gesto de soltar, que é o elemento sob a origem do gesto de arrastar, processa o pacote de dados.

O processo para habilitar o gesto de arrastar e soltar em um aplicativo é o seguinte:

  1. Habilite arrastar um elemento adicionando um objeto DragGestureRecognizer à sua coleção GestureRecognizers. Para obter mais informações, confira Habilitar arrastar.
  2. [opcional] Crie um pacote de dados. O .NET MAUI preenche automaticamente o pacote de dados para controles de imagem e texto, mas para outro conteúdo você precisará construir seu próprio pacote de dados. Para obter mais informações, confira Criar um pacote de dados.
  3. Habilite soltar em um elemento adicionando um objeto DropGestureRecognizer à sua coleção GestureRecognizers. Para obter mais informações, confira Habilitar soltar.
  4. [opcional] Manipule o evento DropGestureRecognizer.DragOver para indicar o tipo de operação permitido pelo destino de soltar. Para obter mais informações, confira Manipular o evento DragOver.
  5. [opcional] Processe o pacote de dados para receber o conteúdo descartado. O MAUI do .NET recuperará automaticamente dados de imagem e texto do pacote de dados, mas para outro conteúdo você precisará processar o pacote de dados. Para obter mais informações, confira Processar o pacote de dados.

Habilitar o gesto de arrastar

No .NET MAUI, o reconhecimento do gesto de arrastar é fornecido pela classe DragGestureRecognizer. Essa classe define as seguintes propriedades:

Essas propriedades são apoiadas por objetos BindableProperty, o que significa que podem ser alvos de associações de dados e ser estilizada.

A classe DragGestureRecognizer também define eventos DragStarting e DropCompleted que são acionados se a propriedade CanDrag for true. Quando um objeto DragGestureRecognizer detecta um gesto de arrastar, ele executa DragStartingCommand e invoca o evento DragStarting. Em seguida, quando o objeto DragGestureRecognizer detecta a conclusão de um gesto de soltar, ele executa DropCompletedCommand e invoca o evento DropCompleted.

O objeto DragStartingEventArgs que acompanha o evento DragStarting define as seguintes propriedades:

  • Cancel, do tipo bool, indica se o evento deve ser cancelado.
  • Data, do tipo DataPackage, indica o pacote de dados que acompanha a fonte de arrastar. Trata-se de uma propriedade somente leitura.
  • PlatformArgs, do tipo PlatformDragStartingEventArgs?, representa os argumentos específicos da plataforma associados ao evento.

No Android, a classe PlatformDragStartingEventArgs define as seguintes propriedades:

  • Sender, do tipo View, representa a exibição nativa anexada ao evento.
  • MotionEvent, do tipo MotionEvent, representa o evento que contém informações para o status de arrastar e soltar.

Além disso, no Android, a classe PlatformDragStartingEventArgs define os seguintes métodos:

  • SetDragShadowBuilder, que define o View.DragShadowBuilder a ser usado quando o gesto de arrastar começa.
  • SetClipData, que define o ClipData a ser usado quando o gesto de arrastar começa.
  • SetLocalData, que define os dados locais a serem usados quando o gesto de arrastar começa.
  • SetDragFlags, que define o DragFlags a ser usado quando o gesto de arrastar começa.

Por exemplo, use o método SetClipData para associar ClipData ao item arrastado:

void OnDragStarting(object sender, DragStartingEventArgs e)
{
#if ANDROID
    string content = "insert your content here";
    e.PlatformArgs.SetClipData(Android.Content.ClipData.NewPlainText("Drag data", content));
#endif
}

O objeto DropCompletedEventArgs que acompanha o evento DropCompleted define uma propriedade PlatformArgs, do tipo PlatformDropCompletedEventArgs?, que representa os argumentos específicos da plataforma associados ao evento.

No Android, a classe PlatformDropCompletedEventArgs define as seguintes propriedades:

  • Sender, do tipo View, representa a exibição nativa anexada ao evento.
  • DragEvent, do tipo DragEvent, representa o evento enviado em vários momentos durante uma operação de arrastar e soltar.

O exemplo XAML a seguir mostra um DragGestureRecognizer anexado a um Image:

<Image Source="monkeyface.png">
    <Image.GestureRecognizers>
        <DragGestureRecognizer />
    </Image.GestureRecognizers>
</Image>

Neste exemplo, um gesto de arrastar pode ser iniciado no Image.

Dica

Um gesto de arrastar é iniciado com uma longa pressão seguida por arrastar.

Criar um pacote de dados

O .NET MAUI criará automaticamente um pacote de dados para você, quando um gesto de arrastar for iniciado, para os seguintes controles:

A tabela a seguir mostra as propriedades que são lidas e qualquer tentativa de conversão que seja feita quando um gesto de arrastar é iniciado em um controle de texto:

Controle Propriedade Conversão
CheckBox IsChecked bool convertido em um string.
DatePicker Date DateTime convertido em um string.
Editor Text
Entry Text
Label Text
RadioButton IsChecked bool convertido em um string.
Switch IsToggled bool convertido em um string.
TimePicker Time TimeSpan convertido em um string.

Para conteúdo diferente de texto e imagens, você precisará criar um pacote de dados por conta própria.

Os pacotes de dados são representados pela classe DataPackage, que define as seguintes propriedades:

A classe DataPackagePropertySet representa um conjunto de propriedades armazenado como um Dictionary<string,object>. Para obter informações sobre a classe DataPackageView, confira Processar o pacote de dados.

Armazenar dados de imagem ou texto

Dados de imagem ou texto podem ser associados a uma fonte de arrastar armazenando os dados na propriedade DataPackage.Image ou DataPackage.Text. Você pode adicionar os dados no manipulador para o evento DragStarting.

O exemplo XAML a seguir mostra um DragGestureRecognizer que registra um manipulador para o evento DragStarting:

<Path Stroke="Black"
      StrokeThickness="4">
    <Path.GestureRecognizers>
        <DragGestureRecognizer DragStarting="OnDragStarting" />
    </Path.GestureRecognizers>
    <Path.Data>
        <!-- PathGeometry goes here -->
    </Path.Data>
</Path>

Neste exemplo, a origem DragGestureRecognizer é anexada a um objeto Path. O evento DragStarting é gerado quando um gesto de arrastar é detectado no Path, que executa o manipulador de eventos OnDragStarting:

void OnDragStarting(object sender, DragStartingEventArgs e)
{
    e.Data.Text = "My text data goes here";
}

O objeto DragStartingEventArgs que acompanha o evento DragStarting tem uma propriedade Data, do tipo DataPackage. Neste exemplo, a propriedade Text do objeto DataPackage é definida como um string. Em seguida, o DataPackage pode ser acessado na lista suspensa, para recuperar o string.

Armazenar dados no conjunto de propriedades

Todos os dados, incluindo imagens e texto, podem ser associados a uma origem de gesto de arrastar armazenando os dados na coleção DataPackage.Properties. Você pode adicionar os dados no manipulador para o evento DragStarting.

O exemplo XAML a seguir mostra um DragGestureRecognizer que registra um manipulador para o evento DragStarting:

<Rectangle Stroke="Red"
           Fill="DarkBlue"
           StrokeThickness="4"
           HeightRequest="200"
           WidthRequest="200">
    <Rectangle.GestureRecognizers>
        <DragGestureRecognizer DragStarting="OnDragStarting" />
    </Rectangle.GestureRecognizers>
</Rectangle>

Neste exemplo, a origem DragGestureRecognizer é anexada a um objeto Rectangle. O evento DragStarting é gerado quando um gesto de arrastar é detectado no Rectangle, que executa o manipulador de eventos OnDragStarting:

void OnDragStarting(object sender, DragStartingEventArgs e)
{
    Shape shape = (sender as Element).Parent as Shape;
    e.Data.Properties.Add("Square", new Square(shape.Width, shape.Height));
}

O objeto DragStartingEventArgs que acompanha o evento DragStarting tem uma propriedade Data, do tipo DataPackage. A coleção Properties do objeto DataPackage, que é uma coleção Dictionary<string, object>, pode ser modificada para armazenar todos os dados necessários. Neste exemplo, o dicionário Properties é modificado para armazenar um objeto Square que representa o tamanho do Rectangle em relação a uma chave "Square".

Habilitar o gesto de soltar

No .NET MAUI, o reconhecimento de gestos de soltar é fornecido pela classe DropGestureRecognizer. Essa classe define as seguintes propriedades:

  • AllowDrop, do tipo bool, que indica se o elemento ao qual o reconhecedor de gestos está anexado pode ser um destino de soltar. O valor padrão dessa propriedade é true.
  • DragOverCommand, do tipo ICommand, que é executado quando a origem de arrastar é arrastada para o destino de soltar.
  • DragOverCommandParameter, do tipo object, que é o parâmetro passado para DragOverCommand.
  • DragLeaveCommand, do tipo ICommand, que é executado quando a origem de arrastar é arrastada para fora do destino de soltar.
  • DragLeaveCommandParameter, do tipo object, que é o parâmetro passado para DragLeaveCommand.
  • DropCommand, do tipo ICommand, que é executado quando a origem de arrastar é solta sobre o destino de soltar.
  • DropCommandParameter, do tipo object, que é o parâmetro passado para DropCommand.

Essas propriedades são apoiadas por objetos BindableProperty, o que significa que podem ser alvos de associações de dados e ser estilizada.

A classe DropGestureRecognizer também define eventos DragOver, DragLeave e Drop que são acionados se a propriedade AllowDrop for true. Quando um DropGestureRecognizer reconhece uma origem de gesto de arrastar sobre o destino do gesto de soltar, ele executa DragOverCommand e invoca o evento DragOver. Em seguida, se a origem do gesto de arrastar for arrastada para fora do destino do gesto de soltar, DropGestureRecognizer executará DragLeave e invocará o evento DragLeaveCommand. Por fim, quando DropGestureRecognizer o reconhece um gesto de soltar sobre o destino do gesto de soltar, ele executa DropCommand e invoca o evento Drop.

A classe DragEventArgs, que acompanha os eventos DragOver e DragLeave, define as seguintes propriedades:

  • Data, do tipo DataPackage, que contém os dados associados à fonte de arrastar. Esta propriedade é somente para leitura.
  • AcceptedOperation, do tipo DataPackageOperation, que especifica quais operações são permitidas pelo destino de soltar.
  • PlatformArgs, do tipo PlatformDragEventArgs?, representa os argumentos específicos da plataforma associados ao evento.

No Android, a classe PlatformDragEventArgs define as seguintes propriedades:

  • Sender, do tipo View, representa a exibição nativa anexada ao evento.
  • DragEvent, do tipo DragEvent, representa o evento enviado em vários momentos durante uma operação de arrastar e soltar.

Para obter informações sobre a enumeração DataPackageOperation, confira Manipular o evento DragOver.

A classe DropEventArgs que acompanha o evento Drop define as seguintes propriedades:

  • Data, do tipo DataPackageView, que é uma versão somente leitura do pacote de dados.
  • Handled, do tipo bool, indica se o manipulador de eventos lidou com o evento ou se o .NET MAUI deve continuar seu próprio processamento.
  • PlatformArgs, do tipo PlatformDropEventArgs?, representa os argumentos específicos da plataforma associados ao evento.

No Android, a classe PlatformDropEventArgs define as seguintes propriedades:

  • Sender, do tipo View, representa a exibição nativa anexada ao evento.
  • DragEvent, do tipo DragEvent, representa o evento enviado em vários momentos durante uma operação de arrastar e soltar.

O exemplo XAML a seguir mostra um DropGestureRecognizer anexado a um Image:

<Image BackgroundColor="Silver"
       HeightRequest="300"
       WidthRequest="250">
    <Image.GestureRecognizers>
        <DropGestureRecognizer />
    </Image.GestureRecognizers>
</Image>

Neste exemplo, quando uma origem de arrastar é descartada no destino de soltar Image, a origem de arrastar é copiada para o destino de soltar se a origem de arrastar for um ImageSource. O .NET MAUI copia automaticamente imagens e texto arrastados para destinos de soltar compatíveis.

Manipular o evento DragOver

O evento DropGestureRecognizer.DragOver pode ser tratado opcionalmente para indicar quais tipos de operações são permitidas pelo destino de soltar. Você pode indicar as operações que podem ser permitidas definindo a propriedade AcceptedOperation, do tipo DataPackageOperation, no objeto DragEventArgs que acompanha o evento DragOver.

A enumeração DataPackageOperation define os seguintes membros:

  • None, indica que nenhuma ação será executada.
  • Copy, indica que o conteúdo da origem de arrastar será copiado para o destino de soltar.

Importante

Quando um objeto DragEventArgs é criado, a propriedade AcceptedOperation usa como padrão DataPackageOperation.Copy.

O exemplo XAML a seguir mostra um DropGestureRecognizer que registra um manipulador para o evento DragOver:

<Image BackgroundColor="Silver"
       HeightRequest="300"
       WidthRequest="250">
    <Image.GestureRecognizers>
        <DropGestureRecognizer DragOver="OnDragOver" />
    </Image.GestureRecognizers>
</Image>

Neste exemplo, DropGestureRecognizer é anexado a um objeto Image. O evento DragOver é gerado quando uma origem de arrastar é arrastada sobre o destino de soltar, mas não é solta, o que executa o manipulador de eventos OnDragOver:

void OnDragOver(object sender, DragEventArgs e)
{
    e.AcceptedOperation = DataPackageOperation.None;
}

Neste exemplo, a propriedade AcceptedOperation do objeto DragEventArgs é definida como DataPackageOperation.None. Este valor garante que nenhuma ação seja tomada quando uma origem de arrastar é descartada sobre o destino do gesto de soltar.

Processar o pacote de dados

O evento Drop é gerado quando uma origem de gesto de arrastar é solta sobre um destino de gesto de soltar. O .NET MAUI tenta recuperar automaticamente dados do pacote de dados quando uma origem de arrastar é solta nos seguintes controles:

A tabela a seguir mostra as propriedades definidas e qualquer tentativa de conversão que seja realizada quando uma origem de arrastar baseada em texto é solta em um controle de texto:

Controle Propriedade Conversão
CheckBox IsChecked string é convertido em um bool.
DatePicker Date string é convertido em um DateTime.
Editor Text
Entry Text
Label Text
RadioButton IsChecked string é convertido em um bool.
Switch IsToggled string é convertido em um bool.
TimePicker Time string é convertido em um TimeSpan.

Para conteúdo diferente de texto e imagens, você precisará processar o pacote de dados por conta própria.

A classe DropEventArgs que acompanha o evento Drop define uma propriedade Data, do tipo DataPackageView. Esta propriedade representa uma versão somente leitura do pacote de dados.

Recuperar dados de imagem ou texto

Dados de imagem ou texto podem ser recuperados de um pacote de dados no manipulador do evento Drop, usando métodos definidos na classe DataPackageView.

A classe DataPackageView inclui métodos GetImageAsync e GetTextAsync. O método GetImageAsync recupera uma imagem do pacote de dados que foi armazenado na propriedade DataPackage.Image e retorna Task<ImageSource>. Da mesma forma, o método GetTextAsync recupera o texto do pacote de dados que foi armazenado na propriedade DataPackage.Text e retorna Task<string>.

O exemplo a seguir mostra um manipulador de eventos Drop que recupera o texto do pacote de dados para um Path:

async void OnDrop(object sender, DropEventArgs e)
{
    string text = await e.Data.GetTextAsync();

    // Perform logic to take action based on the text value.
}

Neste exemplo, os dados de texto são recuperados do pacote de dados usando o método GetTextAsync. Uma ação com base no valor de texto pode ser executada.

Recuperar dados do recipiente de propriedades

Todos os dados podem ser recuperados de um pacote de dados no manipulador do evento Drop acessando a coleção Properties do pacote de dados.

A classe DataPackageView define uma propriedade, Properties do tipo DataPackagePropertySetView. A classe DataPackagePropertySetView representa um conjunto de propriedades somente leitura armazenado como um Dictionary<string, object>.

O exemplo a seguir mostra um manipulador de eventos Drop que recupera dados do recipiente de propriedades de um pacote de dados para um Rectangle:

void OnDrop(object sender, DropEventArgs e)
{
    Square square = (Square)e.Data.Properties["Square"];

    // Perform logic to take action based on retrieved value.
}

Neste exemplo, o objeto Square é recuperado do conjunto de propriedades do pacote de dados, especificando à chave de dicionário "Square". Uma ação com base no valor recuperado pode ser executada.

Arrastar e soltar entre aplicativos

No iOS, Mac Catalyst e Windows, arrastar pode começar em um aplicativo com a operação de soltar correspondente terminando em um aplicativo .NET MAUI. O aplicativo do qual um item é arrastado é o aplicativo de origem e o aplicativo .NET MAUI no qual um item é descartado é o aplicativo de destino .

Não é possível arrastar de um aplicativo de origem para um aplicativo de destino .NET MAUI no Android.

Obter a posição do gesto

A posição na qual ocorreu um gesto de arrastar ou soltar pode ser obtida chamando o método GetPosition em um objeto DragEventArgs, DragStartingEventArgs ou DropEventArgs. O método GetPosition aceita um argumento Element? e retorna uma posição como um objeto Point?:

void OnDragStarting(object sender, DragStartingEventArgs e)
{
    // Position relative to screen
    Point? screenPosition = e.GetPosition(null);

    // Position relative to specified element
    Point? relativeToImagePosition = e.GetPosition(image);
}

O argumento Element? define o elemento em relação ao qual a posição deve ser obtida. Fornecer um valor null como este argumento significa que o método GetPosition retorna um objeto Point? que define a posição do gesto de arrastar ou soltar em relação à tela.