ลากและวางไฟล์ลงใน WPF


107

ฉันต้องการวางไฟล์รูปภาพลงในแอปพลิเคชัน WPF ของฉัน ขณะนี้ฉันมีเหตุการณ์ที่เกิดขึ้นเมื่อฉันวางไฟล์ลง แต่ฉันไม่รู้ว่าจะทำอย่างไรต่อไป ฉันจะรับภาพได้อย่างไร เป็นsenderวัตถุภาพหรือควบคุมได้หรือไม่

private void ImagePanel_Drop(object sender, DragEventArgs e)
{
    //what next, dont know how to get the image object, can I get the file path here?
}

คำตอบ:


214

นี่คือสิ่งที่คุณต้องการทำโดยทั่วไป

private void ImagePanel_Drop(object sender, DragEventArgs e)
{

  if (e.Data.GetDataPresent(DataFormats.FileDrop))
  {
    // Note that you can have more than one file.
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

    // Assuming you have one file that you care about, pass it off to whatever
    // handling code you have defined.
    HandleFileOpen(files[0]);
  }
}

นอกจากนี้อย่าลืมเชื่อมโยงเหตุการณ์ใน XAML รวมถึงการตั้งค่าAllowDropแอตทริบิวต์ด้วย

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>

ใช้งานได้อย่างยอดเยี่ยมเพียงแค่เปลี่ยน "HandleFileOpen (ไฟล์ [0])" ถึง "foreach (ไฟล์สตริงในไฟล์) {Openfile (file);}" - ขอบคุณ :)
Eamonn McEvoy

1
ขออภัย :) ฉันหมายความว่าการลากและวางไม่ทำงาน AllowDropถูกตั้งค่าเป็น True แต่Dropไม่เคยเรียกตัวจัดการเหตุการณ์ เมื่อฉันลากไฟล์ไปบนหน้าต่างฉันเห็นสัญลักษณ์วงกลม "ปฏิเสธ"
mcont

5
ฉันใช้Gridเป็นองค์ประกอบรูทโดยBorderด้านในมีBackgroundคุณสมบัติตั้งค่าเป็นบางอย่าง (สีขาวใช้ได้ แต่ไม่โปร่งใส) ภายในBorderฉันใส่เนื้อหาจริง
mcont

1
การตั้งค่าพื้นหลังเป็นแบบโปร่งใสใช้งานได้ดีสำหรับฉันเมื่อพยายามวางลงบน Grid เห็นได้ชัดว่าคุณต้องการพื้นหลังเพื่อให้การทดสอบ Hit เกิดขึ้น ขอบคุณข้อมูลบล็อกนี้: codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf
DustinA

2
Gotcha ที่แท้จริงอย่างหนึ่งคือถ้าคุณเรียกใช้ VisualStudio ในฐานะผู้ดูแลระบบ - ดีบักแอปของคุณ - และลากจาก FileExplorer ในฐานะที่ไม่ใช่ผู้ดูแลระบบบริบทความปลอดภัยจะแตกต่างกันและไม่มีเหตุการณ์การลากจะทริกเกอร์ ทำให้ชีวิตฉันเสียเวลา 30 นาที
Hans Karlsen

35

ไฟล์ภาพที่มีอยู่ในeพารามิเตอร์ซึ่งเป็นตัวอย่างของระดับDragEventArgs
( senderพารามิเตอร์มีการอ้างอิงถึงออบเจ็กต์ที่ยกเหตุการณ์)

ตรวจสอบe.Dataสมาชิกโดยเฉพาะ ตามที่เอกสารอธิบายจะส่งคืนการอ้างอิงไปยังออบเจ็กต์ข้อมูล ( IDataObject) ที่มีข้อมูลจากเหตุการณ์ลาก

IDataObjectอินเตอร์เฟซที่มีจำนวนของวิธีการสำหรับการดึงข้อมูลวัตถุที่คุณหลังจาก คุณอาจต้องการเริ่มต้นด้วยการเรียกใช้GetFormatsเมธอดเพื่อค้นหารูปแบบของข้อมูลที่คุณกำลังทำงานอยู่ (ตัวอย่างเช่นเป็นภาพจริงหรือเป็นเพียงเส้นทางไปยังไฟล์ภาพ)

จากนั้นเมื่อคุณระบุรูปแบบของไฟล์ที่ลากเข้ามาได้แล้วคุณจะเรียกใช้วิธีการโอเวอร์โหลดแบบใดแบบหนึ่งGetDataเพื่อดึงข้อมูลวัตถุในรูปแบบเฉพาะ


12

นอกจากนี้สำหรับคำตอบของ AR โปรดทราบว่าหากคุณต้องการใช้TextBoxเพื่อวางคุณต้องรู้สิ่งต่อไปนี้

TextBoxDragAndDropดูเหมือนว่าจะมีการเริ่มต้นแล้วในการจัดการบางอย่างสำหรับ หากออบเจ็กต์ข้อมูลของคุณเป็น a Stringมันก็ใช้งานได้ ประเภทอื่นไม่ได้รับการจัดการและคุณจะได้รับเอฟเฟกต์เมาส์ต้องห้ามและตัวจัดการดร็อปของคุณจะไม่ถูกเรียก

ดูเหมือนว่าคุณสามารถเปิดใช้งานการจัดการของคุณเองด้วยe.Handledto trueในPreviewDragOverตัวจัดการเหตุการณ์

XAML

<TextBox AllowDrop="True"    x:Name="RtbInputFile"      HorizontalAlignment="Stretch"   HorizontalScrollBarVisibility="Visible"  VerticalScrollBarVisibility="Visible" />

ค#

RtbInputFile.Drop += RtbInputFile_Drop;            
RtbInputFile.PreviewDragOver += RtbInputFile_PreviewDragOver;

private void RtbInputFile_PreviewDragOver(object sender, DragEventArgs e)
{
    e.Handled = true;
}

private void RtbInputFile_Drop(object sender, DragEventArgs e)
{
     if (e.Data.GetDataPresent(DataFormats.FileDrop))
     {
                // Note that you can have more than one file.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                var file = files[0];                
                HandleFile(file);  
     }
}

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