¿Cómo arrastro y suelto archivos en una aplicación?
He visto esto hecho en el entorno Turbo C++ de Borland , pero no estoy seguro de cómo hacerlo para una aplicación C# en la que estoy trabajando. ¿Existen mejores prácticas o trampas a tener en cuenta?
Algún código de muestra:
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);
}
}
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 activarán!
En Windows Forms, establezca la propiedad AllowDrop del control y luego escuche el evento DragEnter y el evento DragDrop.
Cuando DragEnter
se activa el evento, establezca los argumentos AllowedEffect
en algo distinto de ninguno (por ejemplo, e.Effect = DragDropEffects.Move
).
Cuando DragDrop
se active el evento, obtendrá una lista de cadenas. Cada cadena es la ruta completa al archivo que se elimina.
Debes estar consciente de un problema. Cualquier clase que pase como DataObject en la operación de arrastrar y soltar debe ser serializable. Entonces, si intenta pasar un objeto y no funciona, asegúrese de que se pueda serializar, ya que es casi seguro que ese sea el problema. ¡Esto me ha pillado un par de veces!
Otro problema más:
El código marco que llama a los eventos de arrastre se traga todas las excepciones. Podría pensar que su código de evento se está ejecutando sin problemas, mientras que genera excepciones por todas partes. No puedes verlos porque el framework los roba.
Es por eso que siempre pongo try/catch en estos controladores de eventos, para saber si arrojan alguna excepción. Normalmente pongo un Debugger.Break(); en la parte de captura.
Antes del lanzamiento, después de las pruebas, si todo parece funcionar, los elimino o los reemplazo con un manejo de excepciones real.