Como arrastar e soltar arquivos em um aplicativo?

251

Eu já vi isso feito no ambiente Turbo C ++ da Borland , mas não sei como fazer isso para um aplicativo C # em que estou trabalhando. Existem boas práticas ou dicas a serem observadas?

Uwe Keim
fonte
Você quer dizer arrastar e soltar em um aplicativo C # ou no IDE C #?
JamesSugrue 16/09/08
4
Of cource, C # Application. Ele quer fazer com que o aplicativo seja arrastado e solto.
SLA80
3
Respostas mais úteis no link .
Venkatesh Kumar

Respostas:

505

Algum código de exemplo:

  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);
    }
  }
Hans Passant
fonte
56
Isenção de responsabilidade: pode não funcionar na depuração se você executar o Visual Studio como administrador no Windows 7 ou se executar o programa como administrador. Veja aqui
Matthieu
Como você obtém o conteúdo dos arquivos?
Burnsys
3
@Burnsys se você tem o caminho de arquivo da operação de arrastar, então você pode ler usandoio.File
Smith
1
Ugh, não. Defina a propriedade AllowDrop como True no designer e raciocine a partir daí.
Hans Passant
2
O (string[])elenco é seguro para qualquer FileDropqueda formatada? Ou seja, é possível gerar um FileDropque causará uma exceção de conversão ilegal para string[]? Estou tendo problemas para descobrir isso nos documentos .
kdbanman
140

Esteja ciente dos direitos de segurança do Windows Vista / Windows 7 - se você estiver executando o Visual Studio como administrador, não poderá arrastar arquivos de uma janela do explorador não administrador para o seu programa quando executá-lo no Visual Studio. Os eventos relacionados ao arrasto nem serão disparados! Espero que isso ajude alguém por aí a não perder horas da vida ...

Wayne Uroda
fonte
6
@Wayne Uroda: Eu pensei que meu código não estava funcionando - diabos, estava me dando um grande "Nenhum símbolo" como este en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Então eu vi essa resposta e executei o VS como um não administrador e pronto funciona! Graças um milhão.
Derek W
Não posso agradecer o suficiente por isso, eu teria desistido a menos que encontrasse este post! É tão válido no Windows 10 em 2017 quanto era quando você o escreveu.
Culme
42

No Windows Forms, defina a propriedade AllowDrop do controle e ouça o evento DragEnter e o evento DragDrop.

Quando o DragEnterevento for disparado, defina o argumento AllowedEffectcomo algo diferente de nenhum (por exemplo e.Effect = DragDropEffects.Move).

Quando o DragDropevento for acionado, você obterá uma lista de strings. Cada sequência é o caminho completo para o arquivo que está sendo descartado.

Judah Gabriel Himango
fonte
16

Você precisa estar ciente de uma pegadinha. Qualquer classe que você passar como DataObject na operação de arrastar / soltar deve ser serializável. Portanto, se você tentar passar um objeto, e ele não estiver funcionando, verifique se ele pode ser serializado, pois esse é quase certamente o problema. Isso me chamou a atenção algumas vezes!

Phil Wright
fonte
14

Mais uma pegadinha:

O código da estrutura que chama os eventos Drag engolem todas as exceções. Você pode pensar que seu código de evento está funcionando sem problemas, enquanto jorra exceções por todo o lado. Você não pode vê-los porque a estrutura os rouba.

É por isso que sempre coloco try / catch nesses manipuladores de eventos, 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, eu os removo ou substituo por um tratamento de exceção real.

Guge
fonte
9

Outro problema comum é pensar que você pode ignorar os eventos Form DragOver (ou DragEnter). Normalmente, uso o evento DragOver do formulário para definir o AllowedEffect e o evento DragDrop de um controle específico para manipular os dados descartados.

Craig Eddy
fonte
7

Aqui está algo que eu costumava soltar arquivos e / ou pastas cheias de arquivos. No meu caso, eu estava filtrando *.dwgapenas arquivos e optou por incluir todas as subpastas.

fileListé um IEnumerableou similar No meu caso estava vinculado a um controle WPF ...

var fileList = (IList)FileList.ItemsSource;

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

O manipulador de soltar ...

  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);
    }
  }
Cara de CAD
fonte
3

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

Roland
fonte
0

Você pode implementar o Drag & Drop no WinForms e WPF.

  • WinForm (Arraste da janela do aplicativo)

Você deve adicionar o evento mousemove:

private void YourElementControl_MouseMove(object sender, MouseEventArgs e)

    {
     ...
         if (e.Button == MouseButtons.Left)
         {
                 DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
         }
     ...
    }
  • WinForm (Arraste para a janela do aplicativo)

Você deve adicionar o evento DragDrop:

private void YourElementControl_DragDrop (remetente do objeto, DragEventArgs e)

    {
       ...
       foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
            {
                File.Copy(path, DirPath + Path.GetFileName(path));
            }
       ...
    }

Fonte com código completo .

Ernest Rutherford
fonte