it-swarm-pt.tech

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

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

225
Samuel Paul

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);
    }
  }
473
Hans Passant

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 de administrador para o seu programa ao executá-lo no Visual Studio. Os eventos 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 ...

127
Wayne Uroda

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

Quando o evento DragEnter é acionado, defina a variável AllowedEffect do argumento para algo diferente de none (por exemplo, e.Effect = DragDropEffects.Move).

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

40
Judah Gabriel Himango

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

16
Phil Wright

Ainda outra pegadinha:

O código da estrutura que chama os eventos 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 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, removo ou substituo-os por um tratamento de exceção real.

10
Guge

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

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

var fileList = (IList)FileList.ItemsSource;

Veja https://stackoverflow.com/a/19954958/492 para 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);
    }
  }
7
CAD bloke

Outra pegadinha comum é pensar que você pode ignorar os eventos 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.

6
Craig Eddy

A solução de Judah Himango e Hans Passant está disponível no Designer (atualmente estou usando o VS2015): enter image description here enter image description here

0
Roland