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

251

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

Uwe Keim
la source
Voulez-vous dire glisser-déposer dans une application C # ou dans l'IDE C #?
JamesSugrue
4
Bien sûr, C # Application. Il souhaite rendre son application conviviale par glisser-déposer.
SLA80
3
Des réponses plus utiles au lien .
Venkatesh Kumar

Réponses:

505

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);
    }
  }
Hans Passant
la source
56
Avertissement: cela peut ne pas fonctionner dans le débogage si vous exécutez Visual Studio en tant qu'administrateur dans Windows 7, ou si vous exécutez votre programme en tant qu'administrateur. Voir ici
Matthieu
Comment obtenez-vous le contenu des fichiers?
Burnsys
3
@Burnsys si vous avez le chemin de fichier de l'opération de glissement, alors vous pouvez lire en utilisantio.File
Smith
1
Ugh, non. Définissez la propriété AllowDrop sur True dans le concepteur et raisonnez à partir de là.
Hans Passant
2
Le (string[])plâtre est-il sûr pour toute FileDropgoutte formatée? Autrement dit, est-il possible de générer un FileDropqui provoquera une exception de conversion illégale string[]? J'ai du mal à comprendre cela à partir des documents .
kdbanman
140

Soyez conscient 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 d'explorateur non administrateur vers votre programme lorsque vous l'exécuterez à partir de Visual Studio. Les événements liés à la traînée ne se déclencheront même pas! J'espère que cela aide quelqu'un d'autre à ne pas perdre des heures de sa vie ...

Wayne Uroda
la source
6
@Wayne Uroda: Je pensais que mon code ne fonctionnait pas - diable il me donnait un gros "Pas de symbole" comme celui-ci en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Ensuite, j'ai vu cette réponse et j'ai exécuté VS en tant que non-administrateur et hop ça marche! Mille mercis.
Derek W
Je ne vous remercierai jamais assez pour cela, j'aurais abandonné à moins que je ne trouve ce post! Il est aussi valable dans Windows 10 en 2017 qu'il ne l'était lorsque vous l'avez écrit.
Culme
42

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' DragEnterévénement se déclenche, définissez l'argument AllowedEffectsur autre chose que rien (par exemple e.Effect = DragDropEffects.Move).

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

Judah Gabriel Himango
la source
16

Vous devez être conscient d'un gotcha. Toute classe que vous transmettez en tant que DataObject dans l'opération de glisser / déposer doit être sérialisable. 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 presque certainement le problème. Cela m'a attrapé plusieurs fois!

Phil Wright
la source
14

Encore un autre piège:

Le code d'infrastructure qui appelle les événements Drag engloutit toutes les exceptions. Vous pourriez penser que votre code d'événement fonctionne correctement, alors qu'il émet des exceptions partout. Vous ne pouvez pas les voir parce que le cadre les vole.

C'est pourquoi je mets toujours un try / catch dans ces gestionnaires d'événements, juste pour que je sache s'ils lèvent des exceptions. Je mets généralement un Debugger.Break (); dans la partie de capture.

Avant la sortie, après les tests, si tout semble se comporter, je les supprime ou les remplace par une véritable gestion des exceptions.

Guge
la source
9

Un autre problème courant consiste à 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 AllowEffect, puis l'événement DragDrop d'un contrôle spécifique pour gérer les données supprimées.

Craig Eddy
la source
7

Voici quelque chose que j'ai utilisé pour déposer des fichiers et / ou des dossiers pleins de fichiers. Dans mon cas, je filtrais *.dwguniquement les fichiers et j'ai choisi d'inclure tous les sous-dossiers.

fileListest un IEnumerableou 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 dépôt ...

  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 bloke
la source
3

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

entrez la description de l'image ici

entrez la description de l'image ici

Roland
la source
0

Vous pouvez implémenter Drag & Drop dans WinForms et WPF.

  • WinForm (glisser depuis la fenêtre de l'application)

Vous devez ajouter l'événement 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 (glisser vers la fenêtre de l'application)

Vous devez ajouter un événement DragDrop:

void privé YourElementControl_DragDrop (expéditeur d'objet, DragEventArgs e)

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

Source avec code complet .

Ernest Rutherford
la source