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?
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);
}
}
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 ...
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.
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!
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.
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);
}
}
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.