WPF - Usando Drag and Drop (Arrastar e Soltar)
Neste artigo eu vou mostrar como podemos realizar operações Drag and Drop (arrastar e soltar) em uma aplicação WPF. |
É um recurso nativo das aplicações Windows Forms fácil de implementar e utilizar em diversas aplicações.
E como seria o suporte a essas operações em aplicações WPF ?
As
operações de arrastar-e-soltar normalmente envolvem duas partes: uma origem
(drag) a partir da qual o objeto de origem é arrastado e um destino(drop)
que recebe o objeto.
A fonte (drag) e o destino (drop) podem ser elementos de interface do
usuário no mesmo aplicativo ou em um aplicativo diferente.
O tipo e o número de objetos que podem ser manipulados com drag-and-drop é
completamente arbitrário. Por exemplo, arquivos, pastas e seleções de
conteúdo são alguns dos objetos mais comuns manipulados através de operações
de arrastar-e-soltar.
As ações específicas realizadas durante uma operação de arrastar-e-soltar
são de aplicação específica, e muitas vezes são determinadas pelo contexto.
Por exemplo, arrastar uma seleção de arquivos de uma pasta para outra no
mesmo dispositivo de armazenamento move os arquivos por padrão, enquanto
arrastar arquivos a partir de um Universal Naming
Convention(UNC) compartilha com uma pasta local cópias dos arquivos.
As facilidades das operações drag and drop fornecidas pelo WPF foram
projetadas para ser altamente flexíveis e personalizáveis suportando uma
ampla variedade de cenários. Assim o drag-and-drop suporta manipulação de
objetos dentro de um único aplicativo, ou entre diferentes aplicações, bem
como entre aplicativos WPF e outros aplicativos Windows.
Na WPF, qualquer UIElement ou ContentElement pode participar
de um drag-and-drop. Os eventos e os métodos necessários para operações de
arrastar-e-soltar são definidas na classe DragDrop.
As classes UIElement e ContentElement contêm aliases para os
eventos DragDrop vinculados, de forma que os eventos aparecem na
lista de membros de classe quando um UIElement ou ContentElement for
herdado como um elemento base. Os manipuladores de eventos que estão
conectados a esses eventos estão ligados ao DragDrop subjacente e
recebem a mesma instância de dados de evento.
Os principais eventos envolvidos em uma operação Drag and Drop são:
DragEnter | Ocorre quando um elemento é arrastado para os limites do destino (drop) |
DragLeave | Ocorre quando um elemento é arrastado para fora dos limites do destino (drop) |
DragOver | Ocorre continuamente enquanto um objeto é arrastado (deslocado) dentro do limite do destino |
Drop | Ocorre quando um objeto é lançado(solto) sobre o destino. |
Neste artigo eu vou mostrar um exemplo usando drag and drop onde teremos uma aplicação WPF contendo um controle ListBox sobre o qual o usuário poderá soltar arquivos de forma que ao completar a operação os nomes completos dos arquivos serão exibidos no ListBox.
A aplicação contém um controle Button e um controle TextBox. No controle TextBox o usuário poderá definir o local de destino para onde os arquivos serão copiados e no evento Click do controle Button iremos realizar a cópia dos arquivos que foram arrastados para o ListBox para o local de destino definido.
Para dar
suporte à operação drag and drop usando o controle ListBox na WPF temos que
fazer o seguinte:
- Definir a sua propriedade AllowDrop como True
- Tratar o evento Drop de forma a ler o conteúdo arrastado via argumento
DragEventArgs
Recursos usados :
Criando o projeto no VS 2013
Abra o VS 2013 Express for Windows desktop e clique em New Project;
A seguir selecione Visual Basic -> WPF Application;
Informe o nome Drag_Drop e clique no botão OK;
Abra o arquivo MainWindow.xaml e no modo Design vamos incluir os seguintes controles a partir da ToolBox:
TextBlock
ListBox - name:lb_RelacaoArquivos , AllowDrop=True,
Button - name:btnCopiarArquivos, Click="btnCopiarArquivos_Click"
TextBox - name:txtDestino , Content: C:\Dados\
Label - name:lblDestino, Content: Destino:
Disponha os controles conforme o leiaute da figura abaixo:
O código gerado no arquivo MainWindow.xaml pode ser visto a seguir:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Drag and Drop - WPF" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="305*"/>
<ColumnDefinition Width="212*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Text="Relação de arquivos" FontSize="20" Grid.Row="0" Grid.ColumnSpan="2">
</TextBlock>
<ListBox Name="lb_RelacaoArquivos" Grid.Row="1" AllowDrop="True" Drop="RelacaoArquivos_Drop" Grid.ColumnSpan="2"/>
<Button Name="btnCopiarArquivos" Grid.Row="2" Content="Copiar Arquivos" Click="btnCopiarArquivos_Click" Margin="0,0,69,0"/>
<TextBox x:Name="txtDestino" HorizontalAlignment="Left" Height="23" Margin="14,5,0,0" Grid.Row="2" TextWrapping="Wrap" Text="C:\Dados\" VerticalAlignment="Top" Width="188" Grid.Column="1"/>
<Label x:Name="lblDestino" Content="Destino :" HorizontalAlignment="Left" Margin="241,5,0,0" Grid.Row="2" VerticalAlignment="Top"/>
</Grid>
</Window>
|
Agora vamos tratar o evento Drop do controle ListBox - lb_RelacaoArquivos definindo o código abaixo neste evento no arquivo MainWindow.xaml.vb :
Nota: estou usando o namespace System.IO para acessar as classes que realizam a cópia dos arquivos
Private Sub RelacaoArquivos_Drop(sender As Object, e As DragEventArgs)
Try
Dim arquivos As String() = DirectCast(e.Data.GetData(DataFormats.FileDrop, False), String())
For Each fileName As String In arquivos
lb_RelacaoArquivos.Items.Add(fileName)
Next
Catch ex As Exception
MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error)
End Try
End Sub
|
O código acima obtém o nome e o caminho completo dos arquivos que são arrastados sobre o ListBox.
Agora no evento Click do controle Button vamos definir o código que copia esses arquivos para o diretório de destino definido no controle TextBox - txtDestino :
Private Sub btnCopiarArquivos_Click(sender As Object, e As RoutedEventArgs)
If Directory.Exists(txtDestino.Text) Then
Try
For Each item In lb_RelacaoArquivos.Items
Dim arquivo As String = Path.Combine(txtDestino.Text, New FileInfo(item.ToString()).Name)
If Not File.Exists(arquivo) Then
File.Copy(item.ToString(), arquivo)
End If
Next
MessageBox.Show("Arquivos copiados com sucesso ", "Arquivos Copiados", MessageBoxButton.OK, MessageBoxImage.Information)
Catch ex As Exception
MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error)
End Try
Else
MessageBox.Show("O diretório de destino não existe.", "Erro", MessageBoxButton.OK, MessageBoxImage.Error)
End If
End Sub
|
No código acima verificamos se o diretório de destino existe e percorremos o controle ListBox obtendo os nomes dos arquivos e copiando-os para a pasta de destino.
Executando o projeto e realizando algumas operações drag and drop teremos :
Para poder obter o conteúdo de um diretório que for arrastado e solto sobre o controle ListBox podemos usar o código abaixo no evento Drop:
Private Sub RelacaoArquivos_Drop(sender As Object, e As DragEventArgs)
Try
Dim CaminhoArquivos As New List(Of String)()
For Each s In DirectCast(e.Data.GetData(DataFormats.FileDrop, False), String())
If Directory.Exists(s) Then
'Adiciona arquivos a partir do diretorio
CaminhoArquivos.AddRange(Directory.GetFiles(s))
Else
'Adiciona o caminho
CaminhoArquivos.Add(s)
End If
Next
For Each nomeArquivo As String In CaminhoArquivos
lb_RelacaoArquivos.Items.Add(nomeArquivo)
Next
Catch ex As Exception
MessageBox.Show("Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error)
End Try
End Sub
|
Este código irá obter os nomes de todos os arquivos contidos na raiz do diretório arrastado.
Se o diretório contiver outras pastas com arquivos, para obter os respectivos arquivos teremos que usar recursividade e isso não foi implementado neste código.
No exemplo abaixo vemos os arquivos da pasta ASP.NET 4.5 Features_arquivos sendo exibidos no ListBox após a mesma ser arrastada para o controle :
E como fazemos para arrastar e soltar uma imagem ?
Elementar. Basta definir o código abaixo:
If e.Data.GetDataPresent("FileName") Then |
Pegue o projeto completo aqui: Drag_Drop.zip
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
TreeView - Arrastar e Soltar (Drag and Drop) - Macoratti.net