Как перетащить файлы в приложение?

251

Я видел, как это делается в среде Borland Turbo C ++ , но я не уверен, как это сделать для приложения на C #, над которым я работаю. Есть ли лучшие практики или ошибки, на которые стоит обратить внимание?

Уве Кейм
источник
Вы имеете в виду перетаскивание в приложении C # или в C # IDE?
JamesSugrue
4
Конечно, C # Применение. Он хочет сделать свое приложение дружественным.
SLA80
3
Более полезные ответы по ссылке .
Венкатеш Кумар

Ответы:

505

Пример кода:

  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);
    }
  }
Ганс Пассант
источник
56
Отказ от ответственности: он может не работать в режиме отладки, если вы запускаете Visual Studio от имени администратора в Windows 7 или если ваша программа запускается от имени администратора. Смотрите здесь
Матье
Как вы получаете содержимое файлов?
Burnsys
3
@Burnsys, если у вас есть путь к файлу из операции перетаскивания, то вы можете прочитать, используяio.File
Смит
1
Тьфу, нет. Установите для свойства AllowDrop значение True в конструкторе и объясните его оттуда.
Ганс Пассант
2
Безопасен ли (string[])бросок для любого FileDropотформатированного падения? То есть возможно ли сгенерировать объект FileDrop, который вызовет исключение для недопустимого приведения string[]? У меня проблемы с выяснением этого из документов .
kdbanman
140

Помните о правах безопасности Windows Vista / Windows 7 - если вы используете Visual Studio от имени администратора, вы не сможете перетаскивать файлы из окна, не являющегося администратором, в вашу программу, когда вы запускаете ее из Visual Studio. Связанные с перетаскиванием события даже не сработают! Я надеюсь, что это помогает кому-то еще не тратить часы своей жизни ...

Уэйн Урода
источник
6
@Wayne Uroda: я думал, что мой код не работает - черт возьми, он давал мне большое «Нет символа», как этот en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Потом я увидел этот ответ и запустил VS без прав администратора, и в итоге он работает! Бесконечно благодарен.
Дерек W
Не могу отблагодарить вас за это, я бы сдался, если бы мне не удалось найти этот пост! В Windows 10 он действует так же, как в тот момент, когда вы его писали.
Калм
42

В Windows Forms установите свойство элемента управления AllowDrop, затем прослушайте событие DragEnter и событие DragDrop.

Когда DragEnterсобытие срабатывает, установите аргумент в AllowedEffectзначение, отличное от none (например e.Effect = DragDropEffects.Move).

Когда DragDropсобытие срабатывает, вы получите список строк. Каждая строка - это полный путь к удаляемому файлу.

Иуда Габриэль Химанго
источник
16

Вы должны знать о гоче. Любой класс, который вы передаете как объект DataObject в операции перетаскивания, должен быть сериализуемым. Поэтому, если вы пытаетесь передать объект, и он не работает, убедитесь, что он может быть сериализован, так как это почти наверняка является проблемой. Это поймало меня пару раз!

Фил Райт
источник
14

Еще одна ошибка:

Код платформы, который вызывает Drag-события, поглощает все исключения. Вы можете подумать, что код вашего события работает гладко, в то время как повсюду выделяются исключения. Вы не можете видеть их, потому что рамки крадут их.

Вот почему я всегда помещаю try / catch в эти обработчики событий, просто чтобы знать, генерируют ли они какие-либо исключения. Я обычно ставлю Debugger.Break (); в подвохе.

Перед выпуском, после тестирования, если кажется, что все работает, я удаляю или заменяю их реальной обработкой исключений.

Гуге
источник
9

Другая распространенная ошибка - думать, что вы можете игнорировать события Form DragOver (или DragEnter). Я обычно использую событие DragOver формы, чтобы установить AllowedEffect, а затем событие DragDrop определенного элемента управления для обработки отброшенных данных.

Крейг Эдди
источник
7

Вот кое-что, что я использовал для удаления файлов и / или папок, полных файлов. В моем случае я фильтровал *.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);
    }
  }
CAD CAD
источник
3

Решение Judah Himango и Hans Passant доступно в Designer (в настоящее время я использую VS2015):

введите описание изображения здесь

введите описание изображения здесь

Roland
источник
0

Вы можете реализовать Drag & Drop в WinForms и WPF.

  • WinForm (перетаскивание из окна приложения)

Вы должны добавить событие 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);
         }
     ...
    }
  • WinForm (перетащить в окно приложения)

Вы должны добавить событие DragDrop:

private void YourElementControl_DragDrop (отправитель объекта, DragEventArgs e)

    {
       ...
       foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
            {
                File.Copy(path, DirPath + Path.GetFileName(path));
            }
       ...
    }

Исходный код с полным кодом .

Эрнест Резерфорд
источник