L'ho visto fatto nell'ambiente Turbo C ++ di Borland , ma non sono sicuro di come procedere per un'applicazione C # su cui sto lavorando. Ci sono best practice o gotcha da tenere in considerazione?
L'ho visto fatto nell'ambiente Turbo C ++ di Borland , ma non sono sicuro di come procedere per un'applicazione C # su cui sto lavorando. Ci sono best practice o gotcha da tenere in considerazione?
Risposte:
Qualche codice di esempio:
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);
}
}
io.File
Prestare attenzione ai diritti di sicurezza di Windows Vista / Windows 7: se si esegue Visual Studio come amministratore, non sarà possibile trascinare i file da una finestra Explorer non amministratore nel programma quando lo si esegue da Visual Studio. Gli eventi relativi al trascinamento non si attivano nemmeno! Spero che questo aiuti qualcun altro là fuori a non perdere ore della sua vita ...
In Windows Form, imposta la proprietà AllowDrop del controllo, quindi ascolta l'evento DragEnter e l'evento DragDrop.
Quando l' DragEnter
evento si attiva, imposta l'argomento AllowedEffect
su qualcosa di diverso da nessuno (ad es e.Effect = DragDropEffects.Move
.).
Quando l' DragDrop
evento si attiva, otterrai un elenco di stringhe. Ogni stringa è il percorso completo del file che viene eliminato.
Devi essere consapevole di un gotcha. Qualsiasi classe che passi come DataObject nell'operazione di trascinamento della selezione deve essere serializzabile. Quindi, se provi a passare un oggetto e non funziona, assicurati che possa essere serializzato poiché questo è quasi sicuramente il problema. Questo mi ha colpito un paio di volte!
Ancora un altro gotcha:
Il codice del framework che chiama gli eventi Drag ingoia tutte le eccezioni. Potresti pensare che il tuo codice evento stia funzionando senza intoppi, mentre sta scatenando eccezioni dappertutto. Non puoi vederli perché il framework li ruba.
Ecco perché metto sempre un tentativo in questi gestori di eventi, solo per sapere se generano eccezioni. Di solito metto un Debugger.Break (); nella parte di cattura.
Prima del rilascio, dopo il test, se tutto sembra funzionare, rimuovo o sostituisco questi con una vera gestione delle eccezioni.
Un altro gotcha comune sta pensando che puoi ignorare gli eventi Form DragOver (o DragEnter). In genere utilizzo l'evento DragOver del form per impostare il AllowEffect e quindi l'evento DragDrop di un controllo specifico per gestire i dati rilasciati.
Ecco qualcosa che ho usato per eliminare file e / o cartelle piene di file. Nel mio caso stavo filtrando *.dwg
solo i file e ho scelto di includere tutte le sottocartelle.
fileList
è un IEnumerable
o simile Nel mio caso era associato a un controllo WPF ...
var fileList = (IList)FileList.ItemsSource;
Vedi https://stackoverflow.com/a/19954958/492 per i dettagli di quel trucco.
The Drop Handler ...
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);
}
}
È possibile implementare il trascinamento della selezione in WinForms e WPF.
Devi aggiungere l'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);
}
...
}
È necessario aggiungere l'evento DragDrop:
void privato YourElementControl_DragDrop (mittente oggetto, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}