จะใช้ OpenFileDialog เพื่อเลือกโฟลเดอร์ได้อย่างไร?


296

จะใช้OpenFileDialogเพื่อเลือกโฟลเดอร์ได้อย่างไร?

ฉันจะใช้โครงการต่อไปนี้: https://github.com/scottwis/OpenFileOrFolderDialog

อย่างไรก็ตามฉันประสบปัญหาอย่างหนึ่ง มันใช้GetOpenFileNameฟังก์ชั่นและOPENFILENAMEโครงสร้าง และมีสมาชิกที่มีชื่อOPENFILENAME templateIDมันเป็นตัวระบุสำหรับแม่แบบการโต้ตอบ และโครงการนี้มีres1.rcไฟล์และไดอะล็อกเริ่มต้น templated ด้วย แต่ฉันไม่สามารถหาวิธีแนบไฟล์นี้กับโครงการ C # ของฉันได้

มีวิธีที่ดีกว่าในการใช้OpenFileDialogเพื่อเลือกโฟลเดอร์หรือไม่?


ถ้าคุณเปิดไฟล์โครงการด้วยโปรแกรมแก้ไขคุณจะสังเกตเห็นคุณสมบัติเพิ่มเติมที่ด้านล่าง: <VCIncludePath ... >, <Win32Resource ... > และ <Target Name = "BeforeBuild" ... > คุณจะเห็นว่ามันรัน rc.exe เพื่อรวบรวมไฟล์ทรัพยากร res1.rc (อย่าลืมคัดลอก "resource.h" ไปยังโครงการของคุณด้วย) ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง VisualC และ VCIncludePath ชี้ไปยังตำแหน่งที่เหมาะสม (github ชี้ไปที่เวอร์ชัน VC9.0 หนึ่งจุดและคุณอาจต้องเปลี่ยน) หลังจากรวบรวมไฟล์. rc ไฟล์. res ผลลัพธ์จะถูกเพิ่มเป็นทรัพยากรสำหรับปฏิบัติการของคุณด้วยคำสั่ง Win32Resource
mistika

3
มีวิธีการแฮ็กที่ใช้ OpenFileDialog โดยที่ValidateNamesและCheckFileExistsทั้งคู่ถูกตั้งค่าเป็นเท็จและFileNameได้รับค่าการเยาะเย้ยเพื่อระบุว่ามีการเลือกไดเรกทอรี ฉันพูดแฮกเพราะผู้ใช้สับสนเกี่ยวกับวิธีเลือกโฟลเดอร์ ดูเลือกไฟล์หรือโฟลเดอร์จากกล่องโต้ตอบเดียวกัน
Daniel Ballinger

1
Thanx Dan ชี้ไปที่ OpenFileDialog-Hack! นั่นเป็นวิธีที่ดีกว่า FolderBrowserDialog เพราะ OFD แสดงโฟลเดอร์ที่คั่นไว้ ฯลฯ ดังนั้นทุกคนโดยเฉพาะใน บริษัท ใหญ่ ๆ จะค้นพบอึของพวกเขา FBD จะไม่ทำสิ่งที่ดีมากในสถานที่เหล่านั้น
JayC667

1
@ComradeJoecool ผมได้แปลงความคิดเห็นของฉันไปยังคำตอบ ฉันลองหลายครั้งแล้วและไม่มีปัญหา "ไม่พบไฟล์" คุณกำลังใช้อินสแตนซ์ OpenFileDialog เดียวกันซ้ำอีกครั้งหรือไม่
Daniel Ballinger

1
@DanielBallinger อาฉันพบปัญหาของฉันเนื่องจากฉันใช้ Powershell เพื่อสร้างกล่องโต้ตอบการตั้งค่าValidateNamesและCheckFileExistsการfalseใช้งานไม่ได้ฉันต้องตั้งค่าให้0(หรือเรียนรู้ powershell ดีกว่า)
ComradeJoecool

คำตอบ:


398

โดยทั่วไปคุณต้องการFolderBrowserDialogชั้นเรียน:

แจ้งให้ผู้ใช้เลือกโฟลเดอร์ คลาสนี้ไม่สามารถสืบทอดได้

ตัวอย่าง:

using(var fbd = new FolderBrowserDialog())
{
    DialogResult result = fbd.ShowDialog();

    if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
    {
        string[] files = Directory.GetFiles(fbd.SelectedPath);

        System.Windows.Forms.MessageBox.Show("Files found: " + files.Length.ToString(), "Message");
    }
}

ถ้าคุณทำงานในWPFSystem.Windows.Formsคุณจะต้องเพิ่มการอ้างอิงถึง

คุณยังมีการเพิ่มusing System.IOสำหรับDirectoryชั้น


184
FolderBrowserDialog ขาดการใช้งาน ข้อเสียเปรียบหลักคือมันไม่อนุญาตให้คุณคัดลอกเส้นทางโฟลเดอร์จาก Windows Explorer สำหรับการนำทางอย่างรวดเร็วทำให้ไร้ประโยชน์เมื่อคุณต้องการเจาะลึกมากกว่าสามระดับ ไม่ต้องการเจาะเข้าไปในแต่ละโฟลเดอร์โดยเฉพาะอย่างยิ่งเมื่อการจัดเก็บข้อมูลช้าหรือเมื่อคุณมีโฟลเดอร์จำนวนมากในระดับใดระดับหนึ่ง
mistika

2
คำถามนี้เกี่ยวกับการใช้ OpenFileDialog (OFD) เพื่อเลือกโฟลเดอร์ไม่ใช่ FolderBrowserDialog (FBD) ฉันเห็นด้วยว่า FBD นั้นแย่มากจากมุมมองของผู้ใช้
Michael Paulukonis

25
อีกทางเลือกหนึ่งที่จะโต้ตอบนี้กับเสีย UI ใช้CommonOpenFileDialognew CommonOpenFileDialog { IsFolderPicker = true } :
Aneves

113
ได้โปรดอย่าใช้มันเลย! ผมจำได้ว่าเป็นผู้ใช้ฉันถูกโทษโปรแกรมเมอร์ยากจนเหล่านี้ที่ทำให้ยังแอปอื่นด้วยอันยิ่งใหญ่นี้โต้ตอบมุมมองแบบต้นไม้ (ซึ่งเป็นเพียง FolderBrowserDialog) มันใช้ไม่ได้อย่างสมบูรณ์: พวงของรูตเดอร์, แผงรายการโปรดที่ขาดหายไปและที่น่ากลัวที่สุด - คุณไม่สามารถวางเส้นทางที่นั่นได้! และตอนนี้ในฐานะโปรแกรมเมอร์ฉันเห็นคำแนะนำในการใช้ ... ได้โปรดอย่าทำ
Hi-Angel

2
FolderBrowserDialog มีข้อบกพร่องใหญ่อย่างหนึ่งนอกเหนือจากทุกอย่างที่ผู้ใช้รายอื่นกล่าว ไม่สามารถจำเส้นทางที่เลือกล่าสุดได้!
AleX_

252

ในฐานะที่เป็นหมายเหตุสำหรับผู้ใช้ในอนาคตที่ต้องการหลีกเลี่ยงการใช้FolderBrowserDialogงาน Microsoft เคยเปิดตัว API ที่เรียกว่า WindowsAPICodePack ซึ่งมีกล่องโต้ตอบที่มีประโยชน์ซึ่งเรียกCommonOpenFileDialogว่าสามารถตั้งค่าเป็นIsFolderPickerโหมด API ที่สามารถใช้ได้จากไมโครซอฟท์เป็นแพคเกจ NuGet

CommonOpenFileDialogนี่คือฉันทั้งหมดที่จำเป็นในการติดตั้งและใช้ (NuGet จัดการการอ้างอิง)

Install-Package Microsoft.WindowsAPICodePack-Shell

สำหรับบรรทัดรวม:

using Microsoft.WindowsAPICodePack.Dialogs;

การใช้งาน:

CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
    MessageBox.Show("You selected: " + dialog.FileName);
}

36
ฉันคิดว่านี่เป็นคำตอบที่ใกล้ที่สุดสำหรับ "วิธีใช้ OpenFileDialog เพื่อเลือกโฟลเดอร์" FolderBrowseDialog ใช้ไม่ได้มาก ขอบคุณสำหรับคำตอบนี้
Koray

46
นี่ควรเป็นคำตอบ และโปรดทราบว่าคุณต้องติดตั้งMicrosoft.WindowsAPICodePack.Shellแพคเกจผ่าน NuGet ก่อนจึงจะสามารถใช้งานCommonOpenFileDialogได้
smwikipedia

1
ถ้าคุณใช้สิ่งนี้กับ VS2017 มันจะเปิดหน้าต่างหลักของคุณใหม่
Lokiare

1
หมายเหตุสำหรับFolderBrowserDialogผู้ใช้: การใช้อินสแตนซ์พร้อมกันหลายตัวสามารถสร้างปัญหาได้ นี้CommonOpenFileDialogจะดีกว่า
Alper

9
Microsoft ดูเหมือนจะเผยแพร่ซ้ำอีกครั้งในฐานะWindowsAPICodePack-Shell
NucS

32

มีวิธีการแฮ็กที่ใช้OpenFileDialogที่ValidateNamesและCheckFileExistsทั้งสองถูกตั้งค่าเป็นเท็จและFileNameได้รับค่าการเยาะเย้ยเพื่อบ่งชี้ว่าไดเรกทอรีถูกเลือก

ฉันพูดแฮกเพราะผู้ใช้สับสนเกี่ยวกับวิธีการเลือกโฟลเดอร์ จำเป็นต้องอยู่ในโฟลเดอร์ที่ต้องการแล้วกดเปิดในขณะที่ชื่อไฟล์ระบุว่า "การเลือกโฟลเดอร์"

กล่องโต้ตอบการเลือกโฟลเดอร์ C #

สิ่งนี้ขึ้นอยู่กับการเลือกไฟล์หรือโฟลเดอร์จากไดอะล็อกเดียวกันโดย Denis Stankovski

OpenFileDialog folderBrowser = new OpenFileDialog();
// Set validate names and check file exists to false otherwise windows will
// not let you select "Folder Selection."
folderBrowser.ValidateNames = false;
folderBrowser.CheckFileExists = false;
folderBrowser.CheckPathExists = true;
// Always default to Folder Selection.
folderBrowser.FileName = "Folder Selection.";
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
    string folderPath = Path.GetDirectoryName(folderBrowser.FileName);
    // ...
}

ฉันเห็นใช่ฉันได้รับมันทำงาน สิ่งหนึ่งที่น่ารำคาญก็คือมันFolder Selection.จะถูกตรึงไว้ที่ส่วนท้ายของชื่อไฟล์ดังนี้: C:\Folder Selection.ฉันคิดว่าคุณสามารถลบตัวละครเหล่านั้นออกจากสตริงได้เสมอ ยังคงดูดีกว่า FolderBrowserDialog
สหาย Joecool

มันไม่ได้ผลสำหรับฉัน มันจะไม่อนุญาตให้ฉันเลือกโฟลเดอร์ มันเพิ่งเปิดพวกเขา
Lokiare

1
@ Lokiare นั่นคือสิ่งที่ฉันหมายถึงเมื่อฉันพูดว่ามันเป็นการแฮ็ค ดูคำแนะนำจากวรรคสอง
Daniel Ballinger

2
@ComjoJoecool คุณไม่จำเป็นต้องลบมันด้วยตนเอง นั่นคือสิ่งที่บรรทัดสุดท้ายในรหัสสำหรับ: string folderPath = Path.GetDirectoryName (folderBrowser.FileName);
Heriberto Lugo

Oh! มีปัญหากับวิธีนี้: หากผู้ใช้กดปุ่มขึ้นหรือกลับเมื่อเรียกดูโฟลเดอร์Openปุ่มหลักของกล่องโต้ตอบจะไม่ทำงานตามที่คาดไว้! มันทำให้คุณย้อนกลับไปยังโฟลเดอร์ก่อนหน้า! แต่จะทำงานเมื่อคุณคลิกสองครั้งที่โฟลเดอร์เพื่อเลือกหรือเลือกไฟล์บางไฟล์ภายในแต่ละโฟลเดอร์ (หากมีไฟล์ใด ๆ ที่คุณสามารถเลือกได้)
S.Serpooshan

14

แปลกที่ตอบ / โหวตมาก แต่ไม่มีใครเพิ่มรหัสต่อไปนี้เป็นคำตอบ:

using (var fldrDlg = new FolderBrowserDialog())
{ 
    //fldrDlg.Filter = "Png Files (*.png)|*.png";
    //fldrDlg.Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"

    if (fldrDlg.ShowDialog() == DialogResult.OK)
    {
        //fldrDlg.SelectedPath -- your result
    }
}

9
คำตอบของคุณกับ @ IonicăBizău ตอบต่างกันหรือไม่?
Chetan Mehra

1
ลอจิกเหมือนกัน แต่คำตอบของฉันสั้นกว่ามากและคุณไม่จำเป็นต้องสร้างตัวแปรเพิ่มเติมสำหรับ DialogResult
แอนดรู

2
ดังที่ได้กล่าวไปแล้วมีปัญหาใหญ่กับวิธีนี้: นี่คือไดอะล็อกมุมมองต้นไม้ที่น่ากลัว! คุณไม่สามารถคัดลอก - วางพา ธ ในนั้นคุณต้องเจาะทีละหนึ่งจากโฟลเดอร์รากและไม่มีแผงรายการโปรด!
S.Serpooshan

@ S. Serpooshan ฉันไม่สำคัญ นี่เป็นเพียงตัวอย่างการใช้กล่องโต้ตอบใด ๆ คุณสามารถใช้กล่องโต้ตอบอื่น ๆ ได้ถ้าต้องการ :)
Andrew

9

เสียงที่ฉันชอบคุณเพียงแค่หลังจากที่FolderBrowserDialog


5
ฉันเดาว่าสิ่งนี้กำลังลดลง b / c (ตามที่ Mistika ได้ชี้ไปแล้ว) FolderBrowserDialog นั้นมีการใช้งานที่น่ากลัวและ OP ต้องการใช้ OpenFileDialog อย่างชัดเจน
mbx

3
@mbx บางที เพื่อความเป็นธรรม OP ไม่ได้พูดว่า "ฉันไม่สามารถใช้อะไรได้นอกจาก OpenFileDialog" เมื่อตอนแรกที่ฉันตอบคำถามนี้ (เมื่อ 4 ปีครึ่งที่ผ่านมา ... ) ข้อสันนิษฐานคือ OP เพิ่งไม่รู้ว่าจะให้ผู้ใช้เปิดโฟลเดอร์ได้อย่างไร จริง ๆ แล้วฉันไม่ได้กลับไปที่คำถามนี้หลังจากโพสต์คำตอบนี้ดังนั้นฉันไม่ได้เห็นการอภิปรายเกี่ยวกับการใช้งาน - ฉันไม่ได้พิจารณาเมื่อตอบ
Simon Whitehead

6

นี่คือวิธีแก้ไขปัญหาอื่นที่มีแหล่งที่มาทั้งหมดที่มีอยู่ในไฟล์ ZIP แบบง่าย ๆ

มันนำเสนอ OpenFileDialog ด้วยการตั้งค่าสถานะหน้าต่างเพิ่มเติมที่ทำให้มันทำงานได้เช่นโต้ตอบการเลือกโฟลเดอร์ Windows 7+

ตามเว็บไซต์มันเป็นสาธารณสมบัติ: "ไม่มีใบอนุญาตเช่นคุณมีอิสระที่จะทำและทำตามโค้ดสิ่งที่คุณต้องการ"

ลิงค์ Archive.org:


1
ทำงานอย่างสมบูรณ์แบบ! นอกจากนี้คุณสามารถเลือกหลาย ๆ โฟลเดอร์โดยเพิ่มบรรทัดนี้ใน "FolderSelectDialog.cs": public string [] FileNames {รับ {return ofd.FileNames; }} และการเปลี่ยนแปลง ofd.Multiselect = true; ในตัวสร้าง
Maxter

5

ดูที่ห้องสมุดOokii Dialogsซึ่งมีการใช้งานไดอะล็อกเบราว์เซอร์โฟลเดอร์สำหรับ Windows Forms และ WPF ตามลำดับ

ป้อนคำอธิบายรูปภาพที่นี่

Ookii.Dialogs.WinForms

https://github.com/augustoproiete/ookii-dialogs-winforms


Ookii.Dialogs.Wpf

https://github.com/augustoproiete/ookii-dialogs-wpf


ดี. หมายเหตุ: Ookii.Dialogs ต้องการ Microsoft .NET Framework 4.5 หรือสูงกว่า (ไม่สามารถใช้ใน WinXP)
S.Serpooshan

2
@ S.Serpooshan - ฉันเดาว่าคงไม่ทำงานบน Windows 3.1 PC ของฉันใช่ไหม แต่อย่างจริงจังในปี 2018 ไม่มีใครควรคิดเกี่ยวกับ Windows XP ต่อไป - มันตายไปนานแล้ว
rory.ap

@ rory.ap จริงๆแล้วปัญหาหลักของวิธีนี้สำหรับฉันคือมันไม่แสดงไฟล์เมื่อเรียกดูโฟลเดอร์ บางครั้งมันมีประโยชน์มากที่จะสามารถดูไฟล์ (เช่นรูปภาพที่จะประมวลผล) เมื่อผู้ใช้ต้องการเลือกโฟลเดอร์!
S.Serpooshan

-5

นี่ควรเป็นวิธีที่ชัดเจนที่สุดและตรงไปตรงมา

using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{

   System.Windows.Forms.DialogResult result = dialog.ShowDialog();

   if(result == System.Windows.Forms.DialogResult.OK)
   {
      selectedFolder = dialog.SelectedPath;
   }

}

3
FolderBrowserDialogมีการนำเสนอที่นี่หลายครั้งแล้วและเป็นคำตอบที่ผิด มันเป็นอินเตอร์เฟสที่ล้าสมัยและไม่เป็นมิตรกับผู้ใช้ มันใช้SHBrowseForFolderภายใต้และแม้กระทั่งสถานะเอกสาร"สำหรับ Windows Vista หรือใหม่กว่าขอแนะนำให้คุณใช้IFileDialogกับFOS_PICKFOLDERSตัวเลือกมากกว่าSHBrowseForFolderฟังก์ชั่นสิ่งนี้ใช้กล่องโต้ตอบเปิดไฟล์ในโหมดเลือกโฟลเดอร์และเป็นการใช้งานที่ต้องการ"
Herohtar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.