web-dev-qa-db-fra.com

Comment faire glisser et déposer des fichiers dans une application?

J'ai vu cela dans l'environnement Turbo C++ de Borland, mais je ne suis pas sûr de savoir comment procéder pour une application C # sur laquelle je travaille. Y a-t-il des pratiques exemplaires ou des pièges à surveiller?

225
Samuel Paul

Quelques exemples de code:

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

Tenez compte des droits de sécurité de Windows Vista/Windows 7 - si vous exécutez Visual Studio en tant qu'administrateur, vous ne pourrez pas faire glisser des fichiers d'une fenêtre non-administrateur de l'Explorateur vers votre programme lorsque vous l'exécutez à partir de visual studio. Les événements liés à la traînée ne seront même pas déclenchés! J'espère que cela aidera quelqu'un d'autre à ne pas perdre des heures de sa vie ...

127
Wayne Uroda

Dans Windows Forms, définissez la propriété AllowDrop du contrôle, puis écoutez l'événement DragEnter et l'événement DragDrop.

Lorsque l'événement DragEnter est déclenché, définissez la valeur AllowedEffect de l'argument sur une valeur autre que aucune (par exemple, e.Effect = DragDropEffects.Move).

Lorsque l'événement DragDrop est déclenché, vous obtenez une liste de chaînes. Chaque chaîne représente le chemin d'accès complet au fichier en cours de suppression.

40

Vous devez être au courant d'un gotcha. Toute classe que vous transmettez en tant que DataObject dans l'opération de glisser/déposer doit être Serializable. Donc, si vous essayez de passer un objet et qu'il ne fonctionne pas, assurez-vous qu'il peut être sérialisé, car c'est certainement le problème. Cela m'a attiré plusieurs fois!

16
Phil Wright

Encore un autre gotcha:

Le code d'infrastructure qui appelle les événements Drag engloutit toutes les exceptions. Vous pensez peut-être que votre code d'événement fonctionne correctement, alors qu'il engendre de nombreuses exceptions. Vous ne pouvez pas les voir parce que le cadre les vole.

C'est pourquoi je mets toujours un essai/attrape dans ces gestionnaires d'événements, juste pour savoir s'ils lancent des exceptions. Je mets généralement un Debugger.Break (); dans la partie prise.

Avant la publication, après les tests, si tout semble se comporter, je les supprime ou les remplace par un traitement des exceptions réel.

10
Guge

Voici quelque chose que j'avais l'habitude de déposer des fichiers et/ou des dossiers pleins de fichiers. Dans mon cas, je filtrais uniquement pour les fichiers *.dwg et choisissais d'inclure tous les sous-dossiers.

fileList est une IEnumerable ou similaire Dans mon cas, était lié à un contrôle WPF ... 

var fileList = (IList)FileList.ItemsSource;

Voir https://stackoverflow.com/a/19954958/492 pour plus de détails sur cette astuce.

Le gestionnaire de gouttes ...

  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

Un autre piège courant est de penser que vous pouvez ignorer les événements Form DragOver (ou DragEnter). J'utilise généralement l'événement DragOver du formulaire pour définir le AllowedEffect, puis l'événement DragDrop d'un contrôle spécifique pour gérer les données déposées.

6
Craig Eddy

La solution de Judah Himango et Hans Passant est disponible dans Designer (j'utilise actuellement VS2015):  enter image description here  enter image description here

0
Roland