2008-09-16 11 views
203

Widziałem to zrobić w środowisku Borland Turbo C++, ale nie jestem pewien, jak to zrobić dla aplikacji C#, nad którą pracuję. Czy istnieją dobre praktyki lub gróźb, na które trzeba zwracać uwagę?Jak przeciągać i upuszczać pliki w aplikacji?

+0

Czy oznacza przeciągnij i upuść w aplikacji C# lub do C# IDE ? – JamesSugrue

+2

Z cource, aplikacja C#. Chce, aby jego aplikacja była przyjazna dla użytkownika. – SLA80

+3

Więcej przydatnych odpowiedzi pod adresem [link] (http://helgeklein.com/blog/2010/03/how-to-enable-drag-and-drop-for-an-elevated-mfc-application-on-vistawindows-7 /). –

Odpowiedz

37

W Windows Forms, ustaw właściwość AllowDrop kontrolki, a następnie nasłuchuj zdarzenia DragEnter i DragDrop.

Po wywołaniu zdarzenia DragEnter ustaw argument AllowedEffect na coś innego niż brak (na przykład e.Effect = DragDropEffects.Move).

Po uruchomieniu zdarzenia DragDrop otrzymasz listę ciągów. Każdy ciąg jest pełną ścieżką do odrzucanego pliku.

16

Musisz być świadomy gotcha. Każda klasa, którą przechodzisz jako DataObject w operacji przeciągnij/upuść musi mieć możliwość Serializable. Jeśli więc spróbujesz przekazać obiekt i nie działa, upewnij się, że może być serializowany, ponieważ prawie na pewno jest to problem. To mnie zaskoczyło kilka razy!

6

Innym powszechnym problemem jest myślenie, że można zignorować zdarzenia Form DragOver (lub DragEnter). Zazwyczaj używam zdarzenia DragOver formularza, aby ustawić AllowedEffect, a następnie zdarzenie DragDrop określonej kontrolki, aby obsłużyć upuszczone dane.

439

Niektóre przykładowy kod:

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); 
    } 
    } 
+38

Nota prawna: może nie działać w debugowaniu, jeśli uruchamiasz program Visual Studio jako administrator w systemie Windows 7 lub jeśli uruchamiasz program jako administrator. Zobacz [tutaj] (http://stackoverflow.com/questions/2833709/c-sharp-drag-drop-does-not-work-on-windows-7) – Matthieu

+0

Jak uzyskać zawartość plików? – Burnsys

+3

@Burnsys, jeśli masz ścieżkę do pliku z operacji przeciągania, to możesz odczytać używając 'io.File' – Smith

10

Kolejny haczyka:

Kod ramy, które wywołuje przeciągnij zdarzenia połknąć wszystkie wyjątki. Możesz pomyśleć, że Twój kod zdarzeń działa sprawnie, podczas gdy w każdym miejscu pojawiają się wyjątki. Nie można ich zobaczyć, ponieważ kradną je ramy.

Dlatego zawsze próbowałem/haczyk w tych programach obsługi zdarzeń, więc wiem, czy rzucają jakieś wyjątki. Zwykle umieszczam Debugger.Break(); w części połowowej.

Przed zwolnieniem, po przetestowaniu, jeśli wszystko wydaje się zachowywać, usuwam je lub zastępuję rzeczywistą obsługą wyjątku.

120

Należy pamiętać o uprawnieniach zabezpieczeń Windows Vista/Windows 7 - w przypadku korzystania z programu Visual Studio jako administratora nie będzie można przeciągać plików z okna przeglądarki innego niż administrator do programu po uruchomieniu go z poziomu programu visual studio . Zdarzenia związane z przeciąganiem się nawet nie wystrzelą! Mam nadzieję, że pomoże to komuś innemu nie marnować godzin życia ...

+5

@Wayne Uroda: Myślałem, że mój kod nie działa - heck to dawało mi duży "Brak symbolu" jak ten http://en.wikipedia.org/wiki/File:ProhibitionSign2.svg. Wtedy zobaczyłem tę odpowiedź i uruchomiłem VS jako nie-admin i presto to działa! Stukrotne dzięki. –

+0

Nie mogę ci wystarczająco podziękować za to, zrezygnowałbym, chyba że znalazłem ten post! Jest tak samo ważny w systemie Windows 10 w 2017 roku, jak to było podczas pisania. – Culme

3

Oto coś, co kiedyś upuściłem pliki i/lub foldery pełne plików. W moim przypadku filtrowałem tylko pliki *.dwg i wybrałem wszystkie podfoldery.

fileList jest IEnumerable lub podobne w moim przypadku był zobowiązany do kontroli WPF ...

var fileList = (IList)FileList.ItemsSource; 

Zobacz https://stackoverflow.com/a/19954958/492 o szczegóły tej sztuczki.

Upadek obsługi ...

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); 
    } 
    } 
0

Rozwiązanie Judah Himango i Hans Passant jest dostępna w kreatorze (Obecnie używam VS2015): enter image description here enter image description here

Powiązane problemy