web-development-kb-es.site

¿Cómo puedo arrastrar y soltar archivos en una aplicación?

He visto hacer esto en el entorno Borland Turbo C++ , pero no estoy seguro de cómo hacerlo para una aplicación de C # en la que estoy trabajando. ¿Hay mejores prácticas o errores a tener en cuenta?

229
Samuel Paul

Algunos ejemplos de código:

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

Tenga en cuenta los derechos de seguridad de Windows Vista/Windows 7: si ejecuta Visual Studio como administrador, no podrá arrastrar archivos desde una ventana del Explorador que no sea de administrador a su programa cuando lo ejecute desde Visual Studio. Los eventos relacionados con el arrastre ni siquiera se dispararán! Espero que esto ayude a alguien más por ahí que no pierda horas de su vida ...

132
Wayne Uroda

En Windows Forms, configure la propiedad AllowDrop del control, luego escuche el evento DragEnter y el evento DragDrop.

Cuando se dispare el evento DragEnter, establezca el AllowedEffect del argumento en algo distinto a ninguno (por ejemplo, e.Effect = DragDropEffects.Move).

Cuando se dispare el evento DragDrop, obtendrá una lista de cadenas. Cada cadena es la ruta completa al archivo que se está eliminando.

40

Necesitas estar al tanto de un gotcha. Cualquier clase que pase como DataObject en la operación de arrastrar y soltar tiene que ser serializable. Por lo tanto, si intenta pasar un objeto y no está funcionando, asegúrese de que pueda ser serializado, ya que es casi seguro que el problema. ¡Esto me ha atrapado un par de veces!

16
Phil Wright

Sin embargo, otro gotcha:

El código del marco que llama a los eventos de arrastre traga todas las excepciones. Podría pensar que su código de evento se está ejecutando sin problemas, mientras que está generando excepciones en todo el lugar. No puedes verlos porque el marco los roba.

Es por eso que siempre pongo un try/catch en estos manejadores de eventos, solo para saber si lanzan alguna excepción. Por lo general pongo un Debugger.Break (); en la parte de captura.

Antes del lanzamiento, después de la prueba, si todo parece comportarse, los elimino o sustituyo por el manejo de excepciones reales.

12
Guge

Otro problema común es pensar que se pueden ignorar los eventos Form DragOver (o DragEnter). Por lo general, uso el evento DragOver del formulario para establecer el AllowedEffect, y luego el evento DragDrop de un control específico para manejar los datos soltados.

7
Craig Eddy

Aquí hay algo que solía soltar archivos y/o carpetas llenas de archivos. En mi caso, estaba filtrando solo los archivos de *.dwg y elegí incluir todas las subcarpetas.

fileList es una IEnumerable o similar En mi caso, estaba vinculado a un control WPF ...

var fileList = (IList)FileList.ItemsSource;

Consulte https://stackoverflow.com/a/19954958/492 para obtener detalles de ese truco.

El controlador de caída ...

  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

La solución de Judah Himango y Hans Passant está disponible en el Diseñador (actualmente estoy usando VS2015):  enter image description here  enter image description here 

0
Roland