Klasörleri seçmek için bir OpenFileDialog'u nasıl yapılandırabilirsiniz?


251

VS .NET'te, bir proje için bir klasör seçtiğinizde, bir OpenFileDialog veya SaveFileDialog gibi görünen, ancak yalnızca klasörleri kabul edecek şekilde ayarlanmış bir iletişim kutusu görüntülenir. Bunu gördüğümden beri nasıl yapıldığını bilmek istedim. FolderBrowserDialog'un farkındayım, ancak bu iletişim kutusunu hiç sevmedim. Çok küçük başlar ve bir yol yazabilmemden yararlanmama izin vermez.

Şimdiye kadar .NET'ten bunu yapmanın bir yolu olmadığından neredeyse eminim, ancak yönetilmeyen koddan nasıl yaptığınızı merak ediyorum. İletişim kutusunu sıfırdan tamamen yeniden uygulayamadığından, bu davranışı sağlamak için iletişim kutusunu nasıl değiştirirsiniz?

Ayrıca FolderBrowserDialog farkında olduğumu yeniden ifade etmek istiyorum ama bazen bu şekilde bir iletişim kutusu yapılandırmak için gerçekten merak yanı sıra, ben kullanmak istemiyorum. Sadece FolderBrowserDialog'u kullanmamı söylemek tutarlı bir kullanıcı arayüzü deneyimini sürdürmeme yardımcı oluyor, ancak merakımı tatmin etmiyor, bu yüzden bir cevap olarak sayılmayacak.

Vista'ya özgü bir şey de değil; VS .NET 2003'ten beri bu iletişim kutusunu görüyorum, bu yüzden Win2k ve WinXP'de yapılabilir. Bu, "Bunu yapmak için doğru yolu bilmek istiyorum" sorusundan daha az ve "VS 2003'te ilk kez yapmak istediğimden beri bunu merak ettim" sorusundan daha fazlası. Vista'nın dosya iletişim kutusunun bunu yapmak için bir seçeneği olduğunu anlıyorum, ancak XP'de çalışıyor, bu yüzden işe almak için bir şey yaptıklarını biliyorum . Vista'ya özgü cevaplar cevap değildir, çünkü Vista soru bağlamında mevcut değildir.

Güncelleme: Bir çalışma örneği ile birlikte gelir çünkü Scott Wisniewski yanıtını kabul ediyorum, ama Serge iletişim özelleştirme işaret için kredi hak ediyor (.NET gelen kuşkusuz kötü olan ama does MS bulmaktan bunun için çalışmalarını) ve Mark Ransom muhtemelen bu görev için özel bir iletişim kutusu açtı.


7
codeproject'ten sadece basit bir çözüm codeproject.com/Articles/44914/… [Hem dosyaları hem de klasörleri seçmek için OpenFileDialog'u almanın anahtarı ValidateNames ve CheckFileExists özelliklerini false olarak ayarlamaktır (dialog.ValidateNames = false; dialog.CheckFileExists = false) ve klasörlerin seçildiğinden emin olmak için DosyaAdı'nı özel bir anahtar kelimeye ayarlayın (dialog.FileName = "Klasör Seçimi";).]
Riju

3
Bunu bir cevap olarak gönderin, projem için iş yaptı.
CigarDoug

@Riju'nun takip eden periyotta dialog.FileName = "Folder Selection"olması gerekiyor dialog.FileName = "Folder Selection."mu? Neyse ben her iki şekilde "Aç" ikinci tıklama powershell çalışmak için alınamıyor. CheckFileExists sözde yanlış olsa bile dosya bulunamadı söyleyerek tutar
ComradeJoecool

nvm, powershell ortamında dialog.CheckFileExists = 0yanlış yerine
sorunumu

Yanıtlar:


57

Bir klasör veya dosya açmanıza izin veren bir OpenFileOrFolder iletişim kutusu adlı yazdığım bir iletişim kutusu var.

AcceptFiles değerini false olarak ayarlarsanız, yalnızca klasör kabul etme modunda çalışır.

Kaynağı GitHub'dan buradan indirebilirsiniz


4
Çok ilginç ve düşündüğüm kadar karmaşık. Açıklama ekleme ve ne yaptığını gösterme şansı var mı? Bu, diğer yorumlarla birlikte MS'nin muhtemelen kendi diyaloglarını hazırladığına inanmamı sağlıyor.
OwenP

1
Çözümünüzü oluşturmaya çalışırken aşağıdaki hatayı alıyorum ... ne yazık ki c ++ benim güçlü yanlarımdan ... Hata 1 'afxres.h' içerme dosyasını açamıyor.
Ignacio Soler Garcia

1
@SoMoS ve aynı sorunu olan diğer kullanıcılar: WindowsFormsApplication1.csproj dosyasında 100 satırını düzenleyin, böylece kurulumunuzla eşleşir. Benim durumumda "9.0" ı "10.0" (iki kez) olarak değiştirmek ve "(x86)" (iki kez) kaldırmak zorunda kaldım.
RenniePet

2
Kodu (zip) indirdim ve .h (C) dosyasını buldum ve 'sal.h' dosyasını açamıyor gibi bir hata ile derledim.
Lei Yang

2
Bu çözüm VS2010 ve VS2017'de de çalışmaz!
AleX_

49

Sen kullanabilirsiniz FolderBrowserDialogEx - yeniden kullanılabilir türevi yerleşik FolderBrowserDialog. Bu, bir yol, hatta bir UNC yolu yazmanıza izin verir. Ayrıca bilgisayarlara veya yazıcılara göz atabilirsiniz. Dahili FBD gibi çalışır, ancak ... daha iyi.

(EDIT: Bu iletişim kutusunun dosyaları veya klasörleri seçecek şekilde ayarlanabileceğine dikkat çekmeliydim.)

Tam Kaynak kodu (bir kısa C # modülü). Bedava. MS-Kamu lisansı.

Kullanmak için kod:

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
Rahatsız ettiğim için üzgünüm, sadece bir soru sormak ve "Bu özel şeyi istiyorum, bu diğer şeyleri istemiyorum" ve insanlar neşeyle talep edilmeyen bir şey önermek için sinir bozucu. Bir klasör tarayıcı iletişim kutusu değil, bir dosya tarayıcı iletişim kutusu istedim.
OwenP

15
Sorunun ifade şekli, bana bir klasör seçici iletişim kutusu istiyormuş gibi geliyor - durum böyle değil mi? Her neyse, bu tam olarak aradığım şey +1
Tim

Şimdiye kadarki en iyi cevap
Vasil Popov

1
Bu, cevabın hala sadece bağlantı içeren bir cevap olduğu gerçeğini değiştirmez. Site dışı bir kaynakta barındırılan kodun nasıl kullanılacağını göstermek, bu bağlantı da geçici veya kalıcı olarak kullanılamadığında yardımcı olmaktan çıkar. Kurallar bir nedenden dolayı var ve bu katkı bu kurallarla çelişiyor.
IInspectable

1
Bu cevaba baktım ve görünüşe göre site dışı bir kaynağa başvurmuyor. Yani "diğer her cevap" açıkça yanlıştır. Aşırı tepki verdiğimi düşünüyorsanız, belki de kuralları tartışmak için meta'da bir sorun ortaya çıkarmalısınız. Yapmayacağım. Sadece uygularım.
2018'de 0:15

48

Windows API Kod Paketi var. CommonOpenFileDialogSınıf da dahil olmak üzere kabukla ilgili birçok şey var ( Microsoft.WindowsAPICodePack.Dialogsisim alanında). Bu mükemmel bir çözümdür - yalnızca klasörlerin görüntülendiği olağan açık iletişim kutusu.

İşte nasıl kullanılacağına dair bir örnek:

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

Ne yazık ki Microsoft artık bu paketi göndermiyor, ancak birkaç kişi gayri resmi olarak NuGet'e ikili dosyalar yükledi. Bir örnek burada bulunabilir . Bu paket sadece kabuğa özgü şeylerdir. İhtiyacınız olursa, aynı kullanıcının orijinal pakette daha fazla işlevsellik sunan başka paketleri de vardır.


1
Bunun Windows API Kod Paketi'nde olduğunun farkında değildim - bunu işaret ettiğiniz için teşekkürler.
Patrick Klug

10
CommonOpenFileDialog sınıfı yalnızca Windows Vista veya sonraki sürümlerde bulunur, bu nedenle eski işletim sistemlerinde bir istisna oluşturur
Rachel

1
Windows API Kod Paketi'ne nasıl başvuracağınızı söyleyebilir misiniz?
jeff

1
Arşiv Galerisi kullanımdan kaldırıldı. Ya .. bağlantı diyor böylece Could bu onun için yeni bir yer olabilir?
Varsayılan

3
Bu arada, CommonOpenFileDialog sınıfı Microsoft.WindowsAPICodePack.Dialogs ad alanındadır (bulmam biraz zaman aldı).
morgb

35

Ookii.Dialogs paket tarayıcı iletişim klasörü yeni (Vista stili) etrafında yönetilen sarıcı içerir. Ayrıca eski işletim sistemlerinde de kötüleşir.


2
Harika, BSD tarzı lisanslı açık kaynak!
Roman Starkov

7
tek sorun, hedef olarak .net framework istemci profilini kullanmama izin vermeyeceğim.
Kugel

2
Çok güzel bir çözüm. Bence bu en iyi cevap. Tam 3 yıldır aradığım şey.
Samuel

1
Bu çözümle ilgili başka bir sorun: kullanıcının var olmayan bir yolu yapıştırmasına izin vermez. Küçük bir, nispeten, ama yine de yazık.
Roman Starkov

1
Bir stil klasörü iletişim isteyenler için en iyi pratik cevap OpenFileDialog.
aqua

27

Bunun için FolderBrowserDialog'u kullanmak daha iyidir.

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

9
Bir FolderBrowserDialog kullanmanın daha iyi olduğunun farkındayım . Ne olursa olsun nasıl yapıldığını merak ediyorum. FolderBrowserDialog zaten birçok şekilde kokuyor; Vista'da bile yerler çubuğu yok. Komik ise daha iyi MS şimdiye kadar 3 VS sürümlerinde kaçındı.
OwenP

24
FolderBrowserDialog birçok kullanılabilirlik sorununa sahiptir. Aslında bir uygulamaya koymayı düşünmezdim. Çok daha iyi kullanılabilirliğe sahip bir iletişim kutusu için yazıma bakın
Scott Wisniewski

6
FolderBrowserDialog aşağıdakilere izin vermez: - alttaki metin alanına tam yollar yazın / yapıştırın - Vista'da "Sık Kullanılan Bağlantılar" çubuğunu kullanın
Ara'yı

89
FolderBrowserDialog gerçekten korkunç bir kullanıcı arayüzüdür.
mackenir

32
Cidden, insanlar, LÜTFEN bu can sıkıcı diyaloğu uygulamalarınıza koymayı bırakın. Önceki yorumlarla vurgulandığı gibi ÇOK KÖTÜ UI vardır.
Roman Starkov

23

Arama saat sonra buldum bu cevabı ile leetNightShade için bir çalışma çözümü .

Bu çözümü diğerlerinden daha iyi hale getirdiğine inandığım üç şey var.

  1. Kullanması basit. Projenize yalnızca iki dosya (yine de bir dosyayla birleştirilebilir) eklemenizi gerektirir.
  2. Standart FolderBrowserDialog'a geri dönerXP veya daha eski sistemlerde kullanıldığında .
  3. Yazar, kodu uygun gördüğünüz herhangi bir amaç için kullanma izni verir.

    Ne gibi kod almak ve yapmakta özgür gibi hiçbir lisans yoktur.

Kodu buradan indirin .


@MattDavis: .NET Framework 4.0'da (hem Standart hem de İstemci Profili) çalıştığını doğruladım. Projenize hem FolderSelectDialog.cs hem de Reflector.cs dosyalarını eklediğinizden emin olun. Yine de bir şey ... Windows 8'de mi çalışıyorsunuz? Bir Win7 bilgisayarında test ettim.
Alex Essilfie

@Alex Essilfie, haklısın. Projeme çekerken yanlış bir şey yapmış olmalıydım. Netlik için önceki yorumumu sileceğim.
Matt Davis

Birden fazla seçenek arasında koştu ve bunun en iyisi olduğunu düşünüyorum. Önerme.
Jaded

Windows 10'da benim için çalıştı. İyi basit çözüm
David Wilton

eski sistemlerde yük devretmeye saygı duymak zorunda
Mike M

17

Tam Ses Kopyası , Windows XP'de bu şekilde çalışır. Standart dosya açma iletişim kutusu gösterilir, ancak dosya adı alanı "Dosya adı yoksayılır" metnini içerir.

Sadece burada tahmin, ama iletişim kutusunda önemli bir değişiklik yapıldığında dize açılan kutu düzenleme denetimine enjekte olduğundan şüpheleniyorum. Alan boş olmadığı ve diyalog bayrakları dosyanın varlığını kontrol etmeyecek şekilde ayarlandığı sürece, diyalog normal şekilde kapatılabilir.

Düzenle: Bu düşündüğümden çok daha kolay. İşte C ++ / MFC'deki kod, seçtiğiniz ortama çevirebilirsiniz.

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

Düzenleme 2: Bu C # için çeviri olmalı, ama C # akıcı değilim bu yüzden eğer işe yaramazsa beni vurmayın.

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
}

Düzenleme 3: Son olarak, söz konusu gerçek iletişim kutusuna, Visual Studio 2005'te baktım (daha önce ona erişimim yoktu). Standart dosya açma iletişim kutusu değildir! Spy ++ içindeki pencereleri inceler ve standart bir açık dosya ile karşılaştırırsanız, yapı ve sınıf adlarının eşleşmediğini görürsünüz. Yakından baktığınızda, iletişim kutularının içeriği arasındaki bazı farklılıkları da görebilirsiniz. Sonuç olarak, Microsoft bu özelliği vermek için Visual Studio'daki standart iletişim kutusunun yerini tamamen almıştır. Kendi çözümümü sıfırdan kodlamak istemiyorsanız, çözümüm veya benzer bir şey alabileceğiniz kadar yakın olacaktır.


17

Tamam, ilk noktayı bağlamaya çalışalım ;-) Spy ++ veya Winspector ile biraz oynamak VS Proje Konumundaki Klasör metin kutusunun standart iletişim kutusunun özelleştirilmesi olduğunu gösteriyor. Not Defteri'ndeki gibi standart bir dosya iletişim kutusundaki dosya adı metin kutusuyla aynı alan değildir.

O andan itibaren VS, dosya adını ve dosya türü metin kutularını / birleşik giriş kutularını gizler ve iletişim kutusunun altına kendi bölümünü eklemek için özel bir iletişim şablonu kullanır.

EDIT: İşte böyle bir özelleştirme ve nasıl yapılacağını gösteren bir örnek (Win32. .NET değil):

m_ofn, dosya iletişim kutusunun temelini oluşturan OPENFILENAME yapısıdır. Bu 2 satırı ekleyin:

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

burada IDD_FILEDIALOG_IMPORTXLIFF, iletişim kutusunun altına eklenecek özel bir iletişim şablonu. Aşağıdaki kırmızı renkli kısma bakınız. (kaynak: apptranslator.com )alternatif metin

Bu durumda, özelleştirilmiş bölüm yalnızca bir etiket + köprüdür, ancak herhangi bir iletişim kutusu olabilir. Yalnızca klasör seçimini doğrulamamıza izin veren bir OK düğmesi içerebilir.

Ama diyalogun standart kısmındaki bazı kontrollerden nasıl kurtulacağımızı bilmiyorum.

Bu MSDN makalesinde daha fazla ayrıntı .


1
Bu, geçmişte duyduğum bazı açıklamalar gibi geliyor, ancak kavramın hiç bir örneğini görmedim. MSDN belgelerinde bunu yapma konusunda izlenecek yollar var mı?
OwenP

10

Dosya iletişim kutusunu alt sınıflandırabilir ve tüm denetimlerine erişebilirsiniz. Her birinin pencere tutamağını elde etmek için kullanılabilecek bir tanımlayıcısı vardır. Daha sonra bunları gösterebilir ve gizleyebilir, seçim değişiklikleri vb. Hakkında onlardan mesaj alabilirsiniz. Her şey ne kadar çaba sarf etmek istediğinize bağlıdır.

WTL sınıf desteğini kullanarak bizimki yaptık ve dosya iletişim kutusunu özel yerler çubuğu ve eklenti COM görünümleri içerecek şekilde özelleştirdik.

MSDN , Win32 kullanarak bunun nasıl yapılacağı hakkında bilgi sağlar, bu CodeProject makale bir örnek içerir ve bu CodeProject makale bir .NET örneği sağlar .


10

Bunun gibi bir kod kullanabilirsiniz

  • Filtre dosyaları gizle
  • Dosya adı ilk metni gizle

Dosya adı için metin kutusunu gelişmiş gizlemek için OpenFileDialogEx'e bakmanız gerekir

Kod:

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

Basit ve Windows 7+ için ihtiyacım olan şey
Hao Nguyen

Ayrıca bayraklarda OFN_NOVALIDATE gereklidir
Goblin Alchemist


2

İlk Çözüm

Bunu lyquidity.com Bill Seddon tarafından .NET Win 7 tarzı klasör seçme iletişim kutusunun temizlenmiş bir versiyonu olarak geliştirdim (hiçbir bağlantım yok). (Kodunu bu sayfadaki başka bir cevaptan öğrendim ). Kendi yazdım çünkü çözümü bu odaklanmış amaç için gerekli olmayan ek bir Yansıma sınıfı gerektiriyor, istisna tabanlı akış kontrolü kullanıyor, yansıma çağrılarının sonuçlarını önbelleğe almıyor. Yuvalanmış statik sınıfın, yöntem hiç çağrılmadıysa statik yansıma değişkenlerinin doldurulmaya çalışılamayacağını unutmayın . Yeterince yüksek bir Windows sürümünde değilse Vista öncesi iletişim kutusuna geri döner. Windows 7, 8, 9, 10 ve üstü sürümlerde (teorik olarak) çalışmalıdır.VistaDialogShow

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

Windows Formunda şu şekilde kullanılır:

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

Elbette seçenekleri ve hangi özellikleri ortaya çıkardığı ile oynayabilirsiniz. Örneğin, Vista stili iletişim kutusunda çoklu seçime izin verir.

İkinci Çözüm

Simon Mourier , Windows API ile doğrudan birlikte çalışmayı kullanarak tam olarak aynı işi nasıl yapacağınızı gösteren bir cevap verdi , ancak sürümünün Windows'un eski bir sürümündeyse eski stil iletişim kutusunu kullanması için desteklenmesi gerekir. Ne yazık ki, çözümümü çalıştırdığımda henüz görevini bulamadım. Zehrini adlandır!


Bu iyi iletişim kutusunu boş tutamaçlı bir iletişim kutusu (örn. Konsol tipi uygulamalardan) olarak adlandırmak için benzer kullanım örneği: kutunun hemen dışına derler: var dialog = new FolderSelectDialog {InitialDirectory = "C: \\", Title = " "} kaynağından müzik aktarmak için bir klasör; if (dialog.Show ()) {string myFolder = dialog.FileName; }
Philm

Not: Yorum olarak kullanım örneğimi okumak zordur, bu nedenle: Orijinal kullanımda en önemli değişiklik "example": InitialDirectory ve Title arasında virgül kullanın ..
Philm

1

Bunu Codeproject'den deneyin ( kredi) :

Sanırım bahsettiğinizle aynı iletişim kutusu - belki bir ekran görüntüsü eklerseniz yardımcı olur?

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/… Emin olmadığınızda araştırma yapın. Ne istediğimi açıkladım ve FolderBrowserDialog zaten bir cevap olarak diskalifiye edildi.
OwenP

"FolderBrowserDialog'un farkındayım, ama bu iletişim kutusunu hiç sevmedim. Çok küçük başlıyor ve bir yol yazabilmemden yararlanmama izin vermiyor." Kendinize biraz araştırma yapın - oraya bir yol yazabilirsiniz. Her neyse, bunun belirsiz bir soru olduğunu düşünüyorum, bu konuda iyi şanslar.
demoncodemonkey

@ demoncodemonkey: Yolun bir bölümünü yazamaz ve ardından istediğiniz hedefe gidemezsiniz. FileOpenDialog'un sunduğu seçenekler kadar kullanışlı değil.
Treb

1

Vista'da IFileDialog'u FOS_PICKFOLDERS seçenek seti ile kullanabilirsiniz . Bu, klasörleri seçebileceğiniz OpenFileDialog benzeri pencerenin görüntülenmesine neden olur:

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

Eski Windows için, klasördeki herhangi bir dosyayı seçerek her zaman kandırabilirsiniz.

.NET Framework 2.0 ve sonraki sürümlerde çalışan çalışma örnekleri burada bulunabilir .


1

Bunun gibi bir kod kullanabilirsiniz

Filtre boş bir dizedir. Dosya adı AnyName, ancak boş değil

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

6
Bu eski bir yazı olduğunu biliyorum, ama bunu denemek isteyen herkes uğruna, açmak istediğiniz dizinin kesinlikle alt dizinleri olmadığı sürece aslında çalışmaz. Bu nedenle, kullanıcının bir klasöre göz atmasına ve onu seçmesine ve bazı metin kutusuna klasör yolunu doldurmasına izin vermek istersem, C: \ SomeParentDir \ SomeChildDir dizini varsa kullanıcı asla C: \ SomeParentDir öğesini seçemez, çünkü "sizi alt dizine getirir.
Jim

Güzel deneyin .. ama bu metin kutusunda "AnyFile" sadece kullanıcının metnini geçersiz kılmak için bekliyor gibi UI ile sonuçlanır .. bunun dışında kullanıcı dosyaları da seçebilirsiniz - yeterince iyi değil. but nice try ..
GY


-1

Sorunun yapılandırılmasıyla ilgili olduğunu biliyorum, OpenFileDialogancak Google'ın beni buraya getirdiğini görmek de SADECE klasörleri arıyorsanız, bunun FolderBrowserDialogyerine aşağıdaki başka bir SO sorusu tarafından cevaplanan bir Yerine kullanmanız gerektiğini gösterebilirim.

Vb.net'te açık dosya iletişim kutusunu kullanarak yol nasıl belirtilir?


Yanıltıcı. 1) Tek seçenek bu değil ; 2) Çoğu durumda iyi bir seçim değildir; Yine de, harcanan daha fazla son kullanıcı zamanı ile işlem gören en az kodu gerektirir.
Miyav Kedi 2012
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.