Como faço para arrastar e soltar arquivos em um aplicativo?

Eu vi isso feito no ambiente Turbo C ++ da Borland, mas não tenho certeza de como fazê-lo para um aplicativo C # em que estou trabalhando. Existem melhores práticas ou pegadinhas para procurar?

   

Algum código de amostra:

public partial class Form1 : Form { public Form1() { InitializeComponent(); this.AllowDrop = true; this.DragEnter += new DragEventHandler(Form1_DragEnter); this.DragDrop += new DragEventHandler(Form1_DragDrop); } void Form1_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; } void Form1_DragDrop(object sender, DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string file in files) Console.WriteLine(file); } } 

Esteja ciente dos direitos de segurança do Windows Vista / Windows 7 – se você estiver executando o Visual Studio como administrador, não será possível arrastar arquivos de uma janela do Explorer que não seja do administrador para o programa quando executado no Visual Studio. Os events relacionados ao arrasto não serão acionados! Espero que isso ajude alguém lá fora a não desperdiçar horas da sua vida …

No Windows Forms, defina propriedade AllowDrop do controle e, em seguida, escute evento DragEnter e evento DragDrop.

Quando o evento DragEnter acionado, defina o AllowedEffect do argumento como algo diferente de none (por exemplo, e.Effect = DragDropEffects.Move ).

Quando o evento DragDrop acionado, você receberá uma lista de seqüências de caracteres. Cada string é o caminho completo para o arquivo que está sendo descartado.

Você precisa estar ciente de uma pegadinha. Qualquer class que você passar como o DataObject na operação de arrastar / soltar deve ser Serializable. Portanto, se você tentar passar um object e ele não estiver funcionando, verifique se ele pode ser serializado, já que esse é quase certamente o problema. Isso me pegou algumas vezes!

Ainda outra pegadinha:

O código da estrutura que chama os events Drag engole todas as exceções. Você pode pensar que seu código de evento está sendo executado sem problemas, enquanto está ocorrendo exceções em todo o lugar. Você não pode vê-los porque a estrutura os rouba.

É por isso que eu sempre coloco um try / catch nesses manipuladores de events, apenas para saber se eles lançam alguma exceção. Eu costumo colocar um Debugger.Break (); na parte de captura.

Antes do lançamento, após o teste, se tudo parecer se comportar, removo ou substituo esses por um tratamento de exceção real.

Outra pegadinha comum é pensar que você pode ignorar os events Form DragOver (ou DragEnter). Eu normalmente uso o evento DragOver do formulário para definir o AllowedEffect e, em seguida, um evento DragDrop de um controle específico para manipular os dados descartados.

Aqui está algo que eu usei para soltar arquivos e / ou pastas cheias de arquivos. No meu caso eu estava filtrando apenas por *.dwg e escolhi include todas as subpastas.

fileList é um IEnumerable ou similar No meu caso foi ligado a um controle WPF …

 var fileList = (IList)FileList.ItemsSource; 

Consulte https://stackoverflow.com/a/19954958/492 para obter detalhes desse truque.

O manipulador de queda …

  private void FileList_OnDrop(object sender, DragEventArgs e) { var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop)); var files = dropped.ToList(); if (!files.Any()) return; foreach (string drop in dropped) if (Directory.Exists(drop)) files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories)); foreach (string file in files) { if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg")) fileList.Add(file); } } 

A solução de Judah Himango e Hans Passant está disponível no Designer (atualmente estou usando o VS2015): insira a descrição da imagem aqui insira a descrição da imagem aqui