ฉันจะลากและวางไฟล์ลงในแอปพลิเคชันได้อย่างไร


251

ฉันเคยเห็นสิ่งนี้ทำในสภาพแวดล้อมTurbo C ++ของ Borland แต่ฉันไม่แน่ใจว่าจะทำอย่างไรกับแอปพลิเคชัน C # ที่ฉันกำลังทำงาน มีวิธีปฏิบัติที่ดีที่สุดหรือ gotchas ระวังหรือไม่


คุณหมายถึงการลากและวางในแอปพลิเคชัน C # หรือลงใน C # IDE หรือไม่
JamesSugrue

4
ของ cource, C # แอปพลิเคชัน เขาต้องการลากและวางแอปพลิเคชันของเขาให้เป็นมิตร
SLA80

3
คำตอบที่มีประโยชน์อื่น ๆ ที่เชื่อมโยง
Venkatesh Kumar

คำตอบ:


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 หรือถ้าคุณเรียกใช้โปรแกรมของคุณในฐานะผู้ดูแล ดูที่นี่
Matthieu

คุณจะรับเนื้อหาของไฟล์ได้อย่างไร?
Burnsys

3
@Burnsys ถ้าคุณมี filepath จากการดำเนินการลากแล้วคุณสามารถอ่านได้โดยใช้io.File
สมิ ธ

1
ฮึ ตั้งค่าคุณสมบัติ AllowDrop เป็น True ในตัวออกแบบและเหตุผลจากที่นั่น
Hans Passant

2
เป็น(string[])ที่ปลอดภัยสำหรับการใด ๆ หล่อFileDropลดลง -formatted? นั่นคือมันเป็นไปได้ไหมที่จะสร้างสิ่งFileDropที่จะทำให้เกิดข้อยกเว้นที่ผิดกฎหมายstring[]? ฉันมีปัญหาในการหาว่าจากเอกสาร
kdbanman

140

ระวังสิทธิความปลอดภัยของ windows vista / windows 7 - หากคุณใช้งาน Visual Studio ในฐานะผู้ดูแลระบบคุณจะไม่สามารถลากไฟล์จากหน้าต่าง explorer ที่ไม่ใช่ผู้ดูแลระบบไปยังโปรแกรมของคุณเมื่อคุณเรียกใช้จากภายใน visual studio กิจกรรมที่เกี่ยวข้องกับการลากจะไม่เริ่มทำงาน! ฉันหวังว่านี่จะช่วยให้คนอื่นไม่ต้องเสียเวลากับชีวิตของพวกเขา ...


6
@Wayne Uroda: ฉันคิดว่ารหัสของฉันไม่ได้ทำงาน - ห่ามันก็ให้ฉันใหญ่ "ไม่มีสัญลักษณ์" เช่นนี้en.wikipedia.org/wiki/File:ProhibitionSign2.svg จากนั้นฉันเห็นคำตอบนี้และวิ่ง VS ในฐานะที่ไม่ใช่ผู้ดูแลระบบและใช้งาน presto ได้! ขอบคุณหนึ่งล้าน
Derek W

ไม่สามารถขอบคุณมากพอสำหรับเรื่องนี้ฉันจะยอมแพ้เว้นแต่ฉันจะหาโพสต์นี้เกิดขึ้น! มันใช้ได้ใน Windows 10 ในปี 2560 เหมือนตอนที่คุณเขียนมัน
Culme

42

ใน Windows Forms ตั้งค่าคุณสมบัติ AllowDrop ของตัวควบคุมจากนั้นฟังเหตุการณ์ DragEnter และเหตุการณ์ DragDrop

เมื่อDragEnterเหตุการณ์เกิดขึ้นให้ตั้งค่าอาร์กิวเมนต์เป็นAllowedEffectสิ่งอื่นที่ไม่ใช่ (เช่นe.Effect = DragDropEffects.Move)

เมื่อDragDropเหตุการณ์เริ่มขึ้นคุณจะได้รับรายการสตริง แต่ละสตริงคือพา ธ แบบเต็มไปยังไฟล์ที่กำลังถูกดร็อป


16

คุณต้องระวัง gotcha คลาสใด ๆ ที่คุณผ่านเป็นDataObjectในการดำเนินการลาก / ปล่อยจะต้องเป็น Serializable ดังนั้นหากคุณลองและส่งผ่านวัตถุและมันไม่ทำงานตรวจสอบให้แน่ใจว่ามันสามารถต่อเนื่องได้เนื่องจากมันเกือบจะเป็นปัญหาแน่นอน นี่ทำให้ฉันออกไปสองสามครั้ง!


14

ยังอีก gotcha:

รหัสเฟรมเวิร์กที่เรียกใช้ Drag-events กลืนข้อยกเว้นทั้งหมด คุณอาจคิดว่ารหัสเหตุการณ์ของคุณทำงานได้อย่างราบรื่นในขณะที่มันกำลังไหลออกข้อยกเว้นไปทั่ว คุณมองไม่เห็นเพราะเฟรมเวิร์กขโมยไป

นั่นเป็นเหตุผลที่ฉันมักจะลอง / จับในตัวจัดการเหตุการณ์เหล่านี้เสมอเพื่อให้ฉันรู้ว่าพวกเขาโยนข้อยกเว้นใด ๆ ฉันมักจะใส่ Debugger.Break (); ในส่วนที่จับ

ก่อนการเปิดตัวหลังจากการทดสอบถ้าทุกอย่างดูเหมือนว่าจะทำงานฉันจะลบหรือแทนที่สิ่งเหล่านี้ด้วยการจัดการข้อยกเว้นจริง


9

Gotcha ทั่วไปอีกอย่างหนึ่งกำลังคิดว่าคุณสามารถละเว้นเหตุการณ์ในแบบฟอร์ม 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);
    }
  }


0

คุณสามารถใช้การลาก & วางใน 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:

โมฆะส่วนตัว YourElementControl_DragDrop (ผู้ส่งวัตถุ DragEventArgs e)

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

ที่มาพร้อมกับรหัสเต็ม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.