Bagaimana Anda mengonfigurasi OpenFileDialog untuk memilih folder?


251

Dalam VS. NET, ketika Anda memilih folder untuk proyek, dialog yang terlihat seperti OpenFileDialog atau SaveFileDialog ditampilkan, tetapi diatur untuk menerima folder saja. Sejak saya melihat ini, saya ingin tahu bagaimana melakukannya. Saya mengetahui FolderBrowserDialog, tetapi saya tidak pernah benar-benar menyukai dialog itu. Itu dimulai terlalu kecil dan tidak membiarkan saya mengambil keuntungan dari bisa mengetikkan path.

Saya hampir yakin sekarang tidak ada cara untuk melakukan ini dari .NET, tapi saya juga ingin tahu bagaimana Anda melakukannya dari kode yang tidak dikelola juga. Singkat untuk sepenuhnya menerapkan kembali dialog dari awal, bagaimana Anda memodifikasi dialog untuk memiliki perilaku ini?

Saya juga ingin menyatakan kembali bahwa saya mengetahui FolderBrowserDialog tetapi kadang-kadang saya tidak suka menggunakannya, selain menjadi benar-benar penasaran bagaimana mengkonfigurasi dialog dengan cara ini. Memberitahu saya untuk hanya menggunakan FolderBrowserDialog membantu saya mempertahankan pengalaman UI yang konsisten tetapi tidak memuaskan rasa ingin tahu saya sehingga tidak akan dihitung sebagai jawaban.

Ini bukan hal yang khusus untuk Vista; Saya telah melihat dialog ini sejak VS .NET 2003, jadi itu bisa dilakukan di Win2k dan WinXP. Ini kurang dari pertanyaan "Saya ingin tahu cara yang tepat untuk melakukan ini" dan lebih dari "Saya ingin tahu tentang ini sejak saya pertama kali ingin melakukannya dalam VS 2003" pertanyaan. Saya mengerti bahwa dialog file Vista memiliki opsi untuk melakukan ini, tetapi sudah berfungsi di XP jadi saya tahu mereka melakukan sesuatu untuk membuatnya berfungsi. Jawaban khusus-Vista bukan jawaban, karena Vista tidak ada dalam konteks pertanyaan.

Update: Saya menerima jawaban Scott Wisniewski ini karena dilengkapi dengan sampel bekerja, tapi saya pikir Serge pantas kredit untuk menunjuk ke kustomisasi dialog (yang diakui jahat dari NET tetapi tidak bekerja) dan Mark Ransom untuk mencari tahu bahwa MS mungkin menggulung dialog khusus untuk tugas ini.


7
hanya solusi sederhana dari codeproject codeproject.com/Articles/44914/… [Kunci untuk mendapatkan OpenFileDialog untuk memilih kedua file dan folder adalah dengan mengatur properti ValidateNames dan CheckFileExists ke false (dialog.ValidateNames = false; dialog.CheckFileExists = false) dan atur FileName ke beberapa kata kunci khusus untuk memastikan folder terpilih (dialog.FileName = "Pemilihan Folder";).]
Riju

3
Kirim ini sebagai jawaban, itu berhasil untuk proyek saya.
CigarDoug

@ Riju dialog.FileName = "Folder Selection"seharusnya dialog.FileName = "Folder Selection."dengan periode trailing? Lagi pula saya tidak bisa membuatnya bekerja di PowerShell pada klik kedua "Open". Itu terus mengatakan file tidak ditemukan, meskipun CheckFileExists diduga palsu
ComradeJoecool

nvm, dalam pengaturan powershell dialog.CheckFileExists = 0bukannya false memecahkan masalah saya
ComradeJoecool

Sudahkah Anda mencoba Dialog Ookii untuk WPF ?
C. Augusto Proiete

Jawaban:


57

Saya memiliki dialog yang saya tulis disebut dialog OpenFileOrFolder yang memungkinkan Anda untuk membuka folder atau file.

Jika Anda menetapkan nilai AcceptFiles ke false, maka itu beroperasi hanya dalam menerima mode folder.

Anda dapat mengunduh sumbernya dari GitHub di sini


4
Sangat menarik, dan pasti serumit yang saya bayangkan. Adakah peluang untuk membuat anotasi dan menunjukkan apa fungsinya? Ini bersama dengan komentar lain membuat saya percaya MS mungkin hanya menggulung dialog mereka sendiri.
OwenP

1
Saya mendapatkan kesalahan berikut ketika mencoba membangun solusi Anda ... sayangnya c ++ bukan salah satu dari kekuatan saya ... Kesalahan 1 tidak dapat membuka termasuk file 'afxres.h'.
Ignacio Soler Garcia

1
@SoMoS, dan yang lainnya dengan masalah yang sama: dalam file WindowsFormsApplication1.csproj edit baris 100 sehingga cocok dengan pengaturan Anda. Dalam kasus saya, saya harus mengubah "9.0" menjadi "10.0" (dua kali) dan menghapus "(x86)" (dua kali).
RenniePet

2
Saya mengunduh kode (zip) dan menemukan file .h (C) di, dan dikompilasi dengan kesalahan seperti tidak dapat membuka termasuk file 'sal.h'.
Lei Yang

2
Solusi ini tidak bekerja pada VS2010 dan VS2017!
AleX_

49

Anda dapat menggunakan FolderBrowserDialogEx - turunan yang dapat digunakan kembali dari FolderBrowserDialog bawaan. Yang ini memungkinkan Anda untuk mengetik lintasan, bahkan lintasan UNC. Anda juga dapat menelusuri komputer atau printer dengan itu. Bekerja seperti FBD bawaan, tapi ... lebih baik.

(EDIT: Saya seharusnya menunjukkan bahwa dialog ini dapat diatur untuk memilih file atau folder.)

Kode Sumber lengkap (satu modul C # pendek). Gratis. Lisensi MS-Publik.

Kode untuk menggunakannya:

var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
dlg1.Description = "Select a folder to extract to:";
dlg1.ShowNewFolderButton = true;
dlg1.ShowEditBox = true;
//dlg1.NewStyle = false;
dlg1.SelectedPath = txtExtractDirectory.Text;
dlg1.ShowFullPathInEditBox = true;
dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;

// Show the FolderBrowserDialog.
DialogResult result = dlg1.ShowDialog();
if (result == DialogResult.OK)
{
    txtExtractDirectory.Text = dlg1.SelectedPath;
}

7
Maaf jika saya tersinggung, itu hanya frustasi untuk mengajukan pertanyaan dan mengeja "Saya menginginkan hal yang spesifik ini, bukan hal-hal lain ini" dan meminta orang-orang dengan riang menyarankan hal yang tidak diminta. Saya ingin dialog browser file, bukan dialog browser folder.
OwenP

15
Cara pertanyaannya worded, kedengarannya bagi saya seperti meminta dialog folder picker - bukankah itu masalahnya? Bagaimanapun, inilah tepatnya yang saya cari +1
Tim

Pasti jawaban terbaik sejauh ini
Vasil Popov

1
Itu tidak mengubah fakta, bahwa jawabannya masih merupakan jawaban tautan saja. Menunjukkan cara menggunakan kode yang dihosting di sumber daya di luar situs tidak lagi membantu, ketika tautan itu juga menjadi sementara atau secara permanen tidak tersedia. Aturan ada karena suatu alasan, dan kontribusi ini bertentangan dengan aturan itu.
IInspectable

1
Saya melihat jawaban ini , dan tampaknya tidak merujuk sumber daya di luar situs. Jadi "setiap jawaban lain" jelas salah. Jika Anda merasa saya bereaksi berlebihan, mungkin Anda harus mengajukan masalah pada saat meta untuk membahas aturan. Saya tidak akan. Saya hanya akan menerapkannya.
IInspectable

48

Ada Paket Kode API Windows. Ada banyak hal yang berhubungan dengan shell, termasuk CommonOpenFileDialogkelas (di Microsoft.WindowsAPICodePack.Dialogsnamespace). Ini adalah solusi sempurna - dialog terbuka biasa dengan hanya folder yang ditampilkan.

Berikut adalah contoh cara menggunakannya:

CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();

Sayangnya Microsoft tidak lagi mengirimkan paket ini, tetapi beberapa orang telah mengunggah binari secara tidak resmi ke NuGet. Salah satu contoh dapat ditemukan di sini . Paket ini hanya untuk hal-hal khusus shell. Jika Anda membutuhkannya, pengguna yang sama memiliki beberapa paket lain yang menawarkan lebih banyak fungsi yang ada dalam paket aslinya.


1
Saya tidak menyadari bahwa ini ada dalam Windows API Code Pack - terima kasih telah menunjukkan ini.
Patrick Klug

10
Kelas CommonOpenFileDialog hanya ada di Windows Vista atau yang lebih baru, jadi akan membuang pengecualian pada sistem operasi yang lebih lama
Rachel

1
Bisakah Anda memberi tahu cara merujuk Paket Kode API Windows?
jeff

1
Galeri Arsip telah pensiun. , atau begitulah tautannya mengatakan .. Mungkinkah ini tempat baru untuk itu?
Default

3
By the way, kelas CommonOpenFileDialog berada di namespace Microsoft.WindowsAPICodePack.Dialogs (butuh waktu beberapa saat untuk menemukannya).
morgb

35

The Ookii.Dialogs paket berisi pembungkus dikelola sekitar baru (Vista-gaya) folder dialog browser. Ini juga terdegradasi dengan anggun pada sistem operasi lama.


2
Keren, ini open source berlisensi gaya BSD!
Roman Starkov

7
satu-satunya masalah adalah, saya tidak akan membiarkan saya menggunakan .net framework klien sebagai target.
Kugel

2
Solusi yang sangat bagus Ini menurut saya jawaban terbaik. Persis apa yang saya cari sejak 3 tahun.
Samuel

1
Masalah lain dengan solusi ini: itu tidak memungkinkan pengguna untuk menempel jalur yang tidak ada. Yang kecil, relatif, tapi masih sayang.
Roman Starkov

1
Jawaban praktis terbaik untuk mereka yang menginginkan OpenFileDialogdialog folder gaya.
aqua

27

Lebih baik menggunakan FolderBrowserDialog untuk itu.

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

9
Saya sadar bahwa lebih baik menggunakan FolderBrowserDialog. Saya ingin tahu bagaimana hal itu dilakukan. FolderBrowserDialog bau dalam banyak hal; bahkan di Vista tidak memiliki bilah tempat. Lucu bagaimana jika lebih baik MS telah menghindarinya dalam 3 versi VS sejauh ini.
OwenP

24
FolderBrowserDialog memiliki banyak masalah kegunaan. Saya tidak akan mempertimbangkan untuk memasukkannya ke dalam aplikasi. Lihat posting saya untuk dialog yang memiliki kegunaan yang jauh lebih baik
Scott Wisniewski

6
FolderBrowserDialog tidak memungkinkan untuk: - ketik / tempel path lengkap di bidang teks di bagian bawah - gunakan bilah "Tautan Favorit" di Vista - gunakan Pencarian di Vista
decasteljau

89
FolderBrowserDialog adalah UI yang benar-benar mengerikan.
mackenir

32
Serius, orang-orang, Tolong berhenti menempatkan dialog yang menjengkelkan ini ke dalam aplikasi Anda. Ini memiliki UI SANGAT BURUK seperti yang disorot oleh komentar sebelumnya.
Roman Starkov

23

Setelah berjam-jam mencari saya menemukan jawaban ini dengan leetNightShade ke solusi yang berfungsi .

Ada tiga hal yang saya percaya membuat solusi ini jauh lebih baik daripada yang lainnya.

  1. Mudah digunakan. Ini hanya mengharuskan Anda memasukkan dua file (yang dapat dikombinasikan menjadi satu) di proyek Anda.
  2. Itu jatuh kembali ke FolderBrowserDialog standar ketika digunakan pada XP atau sistem yang lebih lama.
  3. Penulis memberikan izin untuk menggunakan kode untuk tujuan apa pun yang Anda anggap cocok.

    Tidak ada lisensi yang dapat Anda ambil dan lakukan dengan kode apa pun yang Anda inginkan.

Unduh kodenya di sini .


@MattDavis: Saya mengonfirmasi bahwa itu berfungsi pada .NET Framework 4.0 (baik Profil Standar dan Klien). Pastikan Anda memiliki FolderSelectDialog.cs dan Reflector.cs yang ditambahkan ke proyek Anda. Satu hal yang ... apakah Anda menjalankan Windows 8? Saya diuji pada komputer Win7.
Alex Essilfie

@Alex Essilfie, Anda benar. Saya pasti telah melakukan sesuatu yang salah dalam menariknya ke proyek saya. Saya akan menghapus komentar saya sebelumnya untuk kejelasan.
Matt Davis

Berlari melalui banyak pilihan dan berpikir yang satu ini adalah yang terbaik Merekomendasikan.
Jaded

Bekerja di windows 10 untuk saya. Solusi sederhana yang bagus
David Wilton

harus menghormati kegagalan dalam sistem yang lebih lama
Mike M

17

Salinan Audio yang Tepat berfungsi seperti ini di Windows XP. Dialog terbuka file standar ditampilkan, tetapi bidang nama file berisi teks "Nama file akan diabaikan".

Hanya menebak-nebak di sini, tapi saya curiga string tersebut disuntikkan ke kontrol edit kotak kombo setiap kali ada perubahan signifikan pada dialog. Selama isian tidak kosong, dan bendera dialog ditetapkan untuk tidak memeriksa keberadaan file, dialog dapat ditutup secara normal.

Sunting: ini jauh lebih mudah dari yang saya kira. Berikut kode dalam C ++ / MFC, Anda dapat menerjemahkannya ke lingkungan pilihan Anda.

CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this);
dlg.DoModal();

Sunting 2: Ini seharusnya terjemahan ke C #, tapi saya tidak lancar dalam C # jadi jangan tembak saya jika tidak berhasil.

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.FileName = "Filename will be ignored";
openFileDialog1.CheckPathExists = true;
openFileDialog1.ShowReadOnly = false;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    // openFileDialog1.FileName should contain the folder and a dummy filename
}

Sunting 3: Akhirnya melihat dialog aktual yang dimaksud, dalam Visual Studio 2005 (saya tidak memiliki akses ke sana sebelumnya). Ini bukan dialog buka file standar! Jika Anda memeriksa windows di Spy ++ dan membandingkannya dengan file standar terbuka, Anda akan melihat bahwa struktur dan nama kelas tidak cocok. Ketika Anda melihat dari dekat, Anda juga dapat menemukan beberapa perbedaan antara isi dialog. Kesimpulan saya adalah bahwa Microsoft sepenuhnya menggantikan dialog standar di Visual Studio untuk memberikannya kemampuan ini. Solusi saya atau yang serupa akan sedekat yang Anda bisa, kecuali jika Anda mau membuat kode sendiri dari awal.


17

OK, izinkan saya mencoba menghubungkan titik pertama ;-) Bermain sedikit dengan Spy ++ atau Winspector menunjukkan bahwa kotak teks Folder di Lokasi Proyek VS adalah kustomisasi dari dialog standar. Ini bukan bidang yang sama dengan kotak nama file dalam dialog file standar seperti yang ada di Notepad.

Dari sana, saya pikir, VS menyembunyikan nama file dan tipe kotak teks / kotak kombo dan menggunakan templat dialog kustom untuk menambahkan bagiannya sendiri di bagian bawah dialog.

EDIT: Berikut adalah contoh penyesuaian seperti itu dan bagaimana melakukannya (di Win32. Not .NET):

m_ofn adalah struct OPENFILENAME yang mendasari dialog file. Tambahkan 2 baris ini:

  m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
  m_ofn.Flags |= OFN_ENABLETEMPLATE;

di mana IDD_FILEDIALOG_IMPORTXLIFF adalah templat dialog khusus yang akan ditambahkan di bagian bawah dialog. Lihat bagian merah di bawah. (sumber: apptranslator.com )teks alternatif

Dalam hal ini, bagian yang dikustomisasi hanya label + hyperlink tetapi bisa berupa dialog apa pun. Itu bisa berisi tombol OK yang memungkinkan kita memvalidasi pemilihan folder saja.

Tapi bagaimana kita bisa menghilangkan beberapa kontrol di bagian standar dialog, saya tidak tahu.

Lebih detail dalam artikel MSDN ini .


1
Kedengarannya seperti beberapa penjelasan yang pernah saya dengar di masa lalu, tetapi saya belum pernah melihat demonstrasi konsep ini. Apakah ada langkah-langkah dalam dokumentasi MSDN tentang melakukannya?
OwenP

10

Anda dapat mensubklasifikasikan file dialog dan mendapatkan akses ke semua kontrolnya. Masing-masing memiliki pengenal yang dapat digunakan untuk mendapatkan pegangan jendela. Anda kemudian dapat menunjukkan dan menyembunyikannya, mendapatkan pesan dari mereka tentang perubahan pilihan dll. Dll. Itu semua tergantung berapa banyak upaya yang ingin Anda ambil.

Kami melakukannya dengan menggunakan dukungan kelas WTL dan mengkustomisasi dialog file untuk menyertakan bilah tempat khusus dan tampilan COM plug-in.

MSDN menyediakan informasi tentang cara melakukan ini menggunakan Win32, artikel CodeProject ini mencakup contoh , dan artikel CodeProject ini memberikan contoh .NET .


10

Anda dapat menggunakan kode seperti ini

  • Filter ini menyembunyikan file
  • Nama file adalah sembunyikan teks pertama

Untuk menyembunyikan textbox untuk nama file, Anda perlu melihat OpenFileDialogEx

Kode:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

Sederhana dan apa yang saya butuhkan untuk Windows 7+
Hao Nguyen

OFN_NOVALIDATE juga diperlukan dalam bentuk bendera
Alchemist Goblin

5

Saya berasumsi Anda menggunakan Vista menggunakan VS2008? Dalam hal ini saya berpikir bahwa opsi FOS_PICKFOLDERS digunakan ketika memanggil dialog file Vista IFileDialog . Saya khawatir bahwa dalam kode .NET ini akan melibatkan banyak kode interop P / Invoke untuk bekerja.


1
Khusus-Vista; Saya pertama kali melihat ini pada VS 2003 pada Windows XP.
OwenP

2

Solusi Pertama

Saya mengembangkan ini sebagai versi bersih dari .NET Win 7-style folder pilih dialog oleh Bill Seddon dari lyquidity.com (Saya tidak punya afiliasi). (Saya mengetahui kodenya dari jawaban lain di halaman ini ). Saya menulis sendiri karena solusinya memerlukan kelas Refleksi tambahan yang tidak diperlukan untuk tujuan terfokus ini, menggunakan kontrol aliran berbasis pengecualian, tidak men-cache hasil panggilan refleksinya. Perhatikan bahwa VistaDialogkelas statis bersarang adalah agar variabel refleksi statisnya tidak mencoba untuk dipopulasi jika Showmetode ini tidak pernah dipanggil. Itu jatuh kembali ke dialog pra-Vista jika tidak dalam versi Windows yang cukup tinggi. Harus bekerja di Windows 7, 8, 9, 10 dan lebih tinggi (secara teoritis).

using System;
using System.Reflection;
using System.Windows.Forms;

namespace ErikE.Shuriken {
    /// <summary>
    /// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
    /// </summary>
    public class FolderSelectDialog {
        private string _initialDirectory;
        private string _title;
        private string _fileName = "";

        public string InitialDirectory {
            get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
            set { _initialDirectory = value; }
        }
        public string Title {
            get { return _title ?? "Select a folder"; }
            set { _title = value; }
        }
        public string FileName { get { return _fileName; } }

        public bool Show() { return Show(IntPtr.Zero); }

        /// <param name="hWndOwner">Handle of the control or window to be the parent of the file dialog</param>
        /// <returns>true if the user clicks OK</returns>
        public bool Show(IntPtr hWndOwner) {
            var result = Environment.OSVersion.Version.Major >= 6
                ? VistaDialog.Show(hWndOwner, InitialDirectory, Title)
                : ShowXpDialog(hWndOwner, InitialDirectory, Title);
            _fileName = result.FileName;
            return result.Result;
        }

        private struct ShowDialogResult {
            public bool Result { get; set; }
            public string FileName { get; set; }
        }

        private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title) {
            var folderBrowserDialog = new FolderBrowserDialog {
                Description = title,
                SelectedPath = initialDirectory,
                ShowNewFolderButton = false
            };
            var dialogResult = new ShowDialogResult();
            if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
                dialogResult.Result = true;
                dialogResult.FileName = folderBrowserDialog.SelectedPath;
            }
            return dialogResult;
        }

        private static class VistaDialog {
            private const string c_foldersFilter = "Folders|\n";

            private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
            private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
            private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
            private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
            private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
            private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
            private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialogNative+FOS")
                .GetField("FOS_PICKFOLDERS")
                .GetValue(null);
            private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
                .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
            private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
            private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
            private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");

            public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title) {
                var openFileDialog = new OpenFileDialog {
                    AddExtension = false,
                    CheckFileExists = false,
                    DereferenceLinks = true,
                    Filter = c_foldersFilter,
                    InitialDirectory = initialDirectory,
                    Multiselect = false,
                    Title = title
                };

                var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
                s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
                s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
                var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
                s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);

                try {
                    int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
                    return new ShowDialogResult {
                        Result = retVal == 0,
                        FileName = openFileDialog.FileName
                    };
                }
                finally {
                    s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
                }
            }
        }

        // Wrap an IWin32Window around an IntPtr
        private class WindowWrapper : IWin32Window {
            private readonly IntPtr _handle;
            public WindowWrapper(IntPtr handle) { _handle = handle; }
            public IntPtr Handle { get { return _handle; } }
        }
    }
}

Ini digunakan seperti pada Formulir Windows:

var dialog = new FolderSelectDialog {
    InitialDirectory = musicFolderTextBox.Text,
    Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
    musicFolderTextBox.Text = dialog.FileName;
}

Tentu saja Anda bisa bermain-main dengan opsi dan properti apa yang terpapar. Misalnya, ini memungkinkan multiselect di dialog gaya Vista.

Solusi Kedua

Simon Mourier memberikan jawaban yang menunjukkan bagaimana melakukan pekerjaan yang sama persis menggunakan interop terhadap API Windows secara langsung, meskipun versinya harus ditambahkan untuk menggunakan dialog gaya lama jika dalam versi Windows yang lebih lama. Sayangnya, saya belum menemukan posnya ketika saya mengerjakan solusi saya. Namai racunmu!


Contoh penggunaan serupa untuk menyebut dialog halus ini sebagai kotak dialog (mis. Dari aplikasi tipe konsol) dengan handle kosong: kompilasi langsung dari kotak: dialog var = new FolderSelectDialog {InitialDirectory = "C: \\", Title = "Pilih a folder untuk mengimpor musik dari "}; if (dialog.Show ()) {string myFolder = dialog.FileName; }
Philm

Catatan: Contoh penggunaan saya sebagai komentar sulit dibaca, oleh karena itu: Perubahan terpenting ke "contoh" penggunaan asli: Gunakan koma antara InitialDirectory dan Judul ..
Philm

1

Coba yang ini dari Codeproject (kredit ke Nitron):

Saya pikir ini dialog yang sama dengan yang Anda bicarakan - mungkin akan membantu jika Anda menambahkan tangkapan layar?

bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
    bool retVal = false;

    // The BROWSEINFO struct tells the shell how it should display the dialog.
    BROWSEINFO bi;
    memset(&bi, 0, sizeof(bi));

    bi.ulFlags   = BIF_USENEWUI;
    bi.hwndOwner = hOwner;
    bi.lpszTitle = szCaption;

    // must call this if using BIF_USENEWUI
    ::OleInitialize(NULL);

    // Show the dialog and get the itemIDList for the selected folder.
    LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

    if(pIDL != NULL)
    {
        // Create a buffer to store the path, then get the path.
        char buffer[_MAX_PATH] = {'\0'};
        if(::SHGetPathFromIDList(pIDL, buffer) != 0)
        {
            // Set the string value.
            folderpath = buffer;
            retVal = true;
        }       

        // free the item id list
        CoTaskMemFree(pIDL);
    }

    ::OleUninitialize();

    return retVal;
}

images.google.com/... Lakukan riset saat tidak pasti. Saya menggambarkan apa yang saya inginkan, dan FolderBrowserDialog sudah didiskualifikasi sebagai jawaban.
OwenP

"Saya mengetahui FolderBrowserDialog, tapi saya tidak pernah benar-benar menyukai dialog itu. Itu dimulai terlalu kecil dan tidak membiarkan saya mengambil keuntungan dari bisa mengetikkan path." Lakukan riset sendiri - Anda bisa mengetikkan lintasan di sana. Pokoknya saya pikir ini sedikit pertanyaan yang ambigu, jadi semoga berhasil.
demoncodemonkey

@demoncodemonkey: Anda tidak dapat mengetik bagian dari jalur lalu menavigasi ke target yang Anda inginkan. Sejauh ini tidak senyaman opsi yang ditawarkan FileOpenDialog.
Treb

1

Pada Vista Anda dapat menggunakan IFileDialog dengan opsi FOS_PICKFOLDERS yang disetel. Itu akan menyebabkan tampilan jendela seperti OpenFileDialog di mana Anda dapat memilih folder:

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

Untuk Windows yang lebih lama, Anda selalu dapat melakukan trik dengan memilih file apa pun di folder.

Contoh kerja yang berfungsi pada .NET Framework 2.0 dan yang lebih baru dapat ditemukan di sini .


1

Anda dapat menggunakan kode seperti ini

Filter adalah string kosong. Nama file adalah AnyName tetapi tidak kosong

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

6
Saya tahu ini adalah posting lama, tetapi demi siapa pun yang ingin mencoba ini, itu sebenarnya tidak berfungsi kecuali direktori yang ingin Anda buka sama sekali tidak memiliki direktori anak. Jadi jika saya ingin membiarkan pengguna saya menelusuri folder dan memilihnya, dan mengisi path folder di beberapa kotak teks, pengguna tidak akan pernah bisa memilih C: \ SomeParentDir jika direktori C: \ SomeParentDir \ SomeChildDir ada, karena memilih "Buka "hanya membawa Anda ke direktori anak.
Jim

Selamat mencoba .. tetapi ini menghasilkan UI yang mengerikan sebagai "AnyFile" di kotak teks hanya menunggu pengguna untuk mengganti teksnya .. selain itu pengguna juga dapat memilih file - tidak cukup baik. tapi usaha yang bagus ..
GY


-1

Saya tahu pertanyaannya adalah pada konfigurasi OpenFileDialogtetapi melihat bahwa Google membawa saya ke sini saya mungkin juga menunjukkan bahwa jika Anda HANYA mencari folder, Anda harus menggunakan FolderBrowserDialogSebaliknya sebagai dijawab oleh pertanyaan SO lain di bawah ini

Bagaimana cara menentukan jalur menggunakan dialog file terbuka di vb.net?


Menyesatkan. 1) Ini bukan satu-satunya pilihan; 2) Ini bukan pilihan yang baik dalam banyak kasus; Masih membutuhkan kode paling sedikit, diperdagangkan oleh lebih banyak waktu yang dihabiskan pengguna akhir.
Meow Cat 2012
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.