Я бачив це в середовищі Turbo C ++ Borland , але я не впевнений, як це зробити для програми C #, над якою працюю. Чи є найкращі практики чи привітання, на які слід звернути увагу?
Я бачив це в середовищі Turbo C ++ Borland , але я не впевнений, як це зробити для програми C #, над якою працюю. Чи є найкращі практики чи привітання, на які слід звернути увагу?
Відповіді:
Деякі зразки коду:
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
Будьте в курсі прав безпеки Windows vista / Windows 7 - якщо ви використовуєте Visual Studio як адміністратор, ви не зможете перетягувати файли з вікна провідника без адміністратора у вашу програму, коли ви запускаєте його з візуальної студії. Події, пов’язані з перетягуванням, навіть не спрацюють! Я сподіваюся, що це допомагає комусь іншому там не витрачати години свого життя ...
У Windows Forms встановіть властивість AllowDrop управління, а потім прослухайте події DragEnter та події DragDrop.
Коли DragEnter
подія спрацьовує, встановіть аргумент AllowedEffect
на щось інше (наприклад e.Effect = DragDropEffects.Move
).
Коли DragDrop
подія розпочнеться, ви отримаєте список рядків. Кожен рядок - це повний шлях до файлу, що випадає.
Ви повинні бути в курсі гатчі. Будь-який клас, який ви передаєте як DataObject в операції перетягування / падіння, повинен бути серіалізаційним. Тож якщо ви спробуєте передати об’єкт, і він не працює, переконайтеся, що його можна серіалізувати, оскільки це майже напевно проблема. Це мене кілька разів піймало!
Ще одна готча:
Рамковий код, що викликає події Drag, поглинає всі винятки. Ви можете подумати, що код події працює безперебійно, в той час як він повсякчас сильно виключає винятки. Ви не можете їх бачити, оскільки рамка їх краде.
Ось чому я завжди вкладаю спробу / лову в ці обробники подій, просто так я знаю, чи вони викидають якісь винятки. Я зазвичай ставлю Debugger.Break (); у частині улову.
Перед випуском після тестування, якщо все, здається, поводиться, я видаляю або замінюю їх реальною обробкою виключень.
Інша поширена проблема - це те, що ви можете ігнорувати події DragOver форми (або DragEnter). Зазвичай я використовую подію DragOver форми для встановлення AllowedEffect, а потім події DragDrop конкретного елемента управління для обробки викинутих даних.
Ось щось я використав для видалення файлів та / або папок, повних файлів. У моєму випадку я фільтрував *.dwg
лише файли і вирішив включити всі підпапки.
fileList
є IEnumerable
або аналогічним В моєму випадку був прив'язаний до елементу управління WPF ...
var fileList = (IList)FileList.ItemsSource;
Детальну інформацію про цей трюк див. На https://stackoverflow.com/a/19954958/492 .
Обробник крапель ...
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);
}
}
Ви можете реалізувати Drag & Drop в WinForms та WPF.
Ви повинні додати подію переміщення миші:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e)
{
...
if (e.Button == MouseButtons.Left)
{
DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
}
...
}
Ви повинні додати подію DragDrop:
приватна недійсна YourElementControl_DragDrop (відправник об'єкта, DragEventArgs e)
{
...
foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
{
File.Copy(path, DirPath + Path.GetFileName(path));
}
...
}