262

In VS .NET, when you are selecting a folder for a project, a dialog that looks like an OpenFileDialog or SaveFileDialog is displayed, but is set up to accept only folders. Ever since I've seen this I've wanted to know how it's done. I am aware of the FolderBrowserDialog, but I've never really liked that dialog. It starts too small and doesn't let me take advantage of being able to type a path.

I'm almost certain by now there's not a way to do this from .NET, but I'm just as curious how you do it from unmanaged code as well. Short of completely reimplementing the dialog from scratch, how do you modify the dialog to have this behavior?

I'd also like to restate that I am aware of the FolderBrowserDialog but sometimes I don't like to use it, in addition to being genuinely curious how to configure a dialog in this manner. Telling me to just use the FolderBrowserDialog helps me maintain a consistent UI experience but doesn't satisfy my curiosity so it won't count as an answer.

It's not a Vista-specific thing either; I've been seeing this dialog since VS .NET 2003, so it is doable in Win2k and WinXP. This is less of a "I want to know the proper way to do this" question and more of a "I have been curious about this since I first wanted to do it in VS 2003" question. I understand that Vista's file dialog has an option to do this, but it's been working in XP so I know they did something to get it to work. Vista-specific answers are not answers, because Vista doesn't exist in the question context.

Update: I'm accepting Scott Wisniewski's answer because it comes with a working sample, but I think Serge deserves credit for pointing to the dialog customization (which is admittedly nasty from .NET but it does work) and Mark Ransom for figuring out that MS probably rolled a custom dialog for this task.

Steve
  • 213,761
  • 22
  • 232
  • 286
OwenP
  • 24,950
  • 13
  • 65
  • 102
  • 7
    just a simple solution from codeproject http://www.codeproject.com/Articles/44914/Select-file-or-folder-from-the-same-dialog [The key to getting OpenFileDialog to select both files and folders is to set the ValidateNames and CheckFileExists properties to false (dialog.ValidateNames = false; dialog.CheckFileExists = false) and set FileName to some special keyword to make sure that folders get selected (dialog.FileName = "Folder Selection";).] – Riju Mar 10 '15 at 09:27
  • 3
    Submit this as an answer, it did the job for my project. – CigarDoug Jul 22 '15 at 13:50
  • @Riju is `dialog.FileName = "Folder Selection"` supposed to be `dialog.FileName = "Folder Selection."` with the trailing period? anyway I cant get it to work in powershell on the second click of "Open" either way. It keeps saying file not found, even though CheckFileExists is supposedly false – ComradeJoecool May 10 '18 at 00:13
  • nvm, in powershell setting `dialog.CheckFileExists = 0` instead of false solved my issue – ComradeJoecool May 10 '18 at 00:39
  • Have you tried the [Ookii Dialogs for WPF](https://github.com/caioproiete/ookii-dialogs-wpf)? – C. Augusto Proiete Oct 04 '18 at 03:23
  • I shared another working answer here: https://stackoverflow.com/a/76245608/8458887 – Hellboy. May 14 '23 at 15:24

17 Answers17

61

I have a dialog that I wrote called an OpenFileOrFolder dialog that allows you to open either a folder or a file.

If you set its AcceptFiles value to false, then it operates in only accept folder mode.

You can download the source from GitHub here

SSteve
  • 10,550
  • 5
  • 46
  • 72
Scott Wisniewski
  • 24,561
  • 8
  • 60
  • 89
  • 4
    Very interesting, and definitely as complicated as I had figured. Any chance of annotating it and pointing out what it does? This along with other comments leads me to believe MS probably just rolled their own dialog. – OwenP Feb 05 '09 at 20:56
  • 1
    I get the following error when trying to build your solution ... unfortunately c++ in not one of my strengths ... Error 1 cannot open include file 'afxres.h'. – Ignacio Soler Garcia Jun 17 '11 at 16:11
  • 1
    @SoMoS, and others with the same problem: in file WindowsFormsApplication1.csproj edit line 100 so it matches your setup. In my case I had to change "9.0" to "10.0" (twice) and remove " (x86)" (twice). – RenniePet Jul 16 '11 at 01:41
  • I think simply using the Microsoft Windows API Pack is a better solution: http://stackoverflow.com/questions/31059/how-do-you-configure-an-openfiledialog-to-select-folders/4998682#4998682 – Patrick Klug Sep 29 '11 at 05:40
  • @PatrickKlug My dialog actually allows you to open both files and folders at the same time (i.e. it has a mode where "Pick Files" AND "Pick Folders" are both true at the same time). But if you don't need that, or prefer the one from Microsoft, then by all means, please use it. – Scott Wisniewski Sep 29 '11 at 13:34
  • This isn't quite a drag-and-drop solution as much as the Ookii framework is. I just want it to work, I don't want to muck about in the source. – aqua May 14 '13 at 01:22
  • 1
    +1 for a very good ([in spite of buggy library navigation](https://github.com/scottwis/OpenFileOrFolderDialog/issues/1)). I'd recommend you put all code in one file or provide a pre-built solution to make usage simpler. – Alex Essilfie Jun 09 '13 at 14:27
  • 2
    I downloaded the code(zip) and found .h(C) file in, and compiled with error such as cannot open include file 'sal.h'. – Lei Yang Jan 03 '14 at 15:37
  • I extracted it to some folder, I opened it in VS 2013, it said it needs to make some modifications to open it in that. I said ok. I clicked play and got this error. It doesn't highlight any particular line. http://i.imgur.com/wPa986V.png I am on windows 7. – barlop May 19 '16 at 20:05
  • 2
    This solution does not work on VS2010 and VS2017 either! – AleX_ Apr 13 '17 at 14:11
  • The msbuild file has a custom action that runs the native resource compiler (rc.exe). Make sure you have the c++ tools installed. You may need to update the paths in the build file as well. There are likely env variables you can use. I no longer have a windows machine, and haven't for a few years now, so I can't test the necessary build updates. If you want to make the necessary build tweaks you can contribute to the project. – Scott Wisniewski Apr 13 '17 at 16:12
  • The WindowsCodePack through built-in NuGet is so straightforward and also seems well-used I think it must be the best answer. – Mike M Dec 10 '17 at 02:09
  • Theres a bug with systems with RAM>8GB (uint maxVal). change hWnd.SendMessage(msg, InteropUtil.NumberOfFileChars, unchecked((uint)buffer)); to hWnd.SendMessage(msg, InteropUtil.NumberOfFileChars, unchecked((ulong)buffer)); Obviously change the function signature too. Solved me finaly the issues – ephraim Nov 05 '18 at 18:58
52

There is the Windows API Code Pack. It's got a lot of shell related stuff, including the CommonOpenFileDialog class (in the Microsoft.WindowsAPICodePack.Dialogs namespace). This is the perfect solution - the usual open dialog with only folders displayed.

Here is an example of how to use it:

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

Unfortunately Microsoft no longer ships this package, but several people have unofficially uploaded binaries to NuGet. One example can be found here. This package is just the shell-specific stuff. Should you need it, the same user has several other packages which offer more functionality present in the original package.

Ken Wayne VanderLinde
  • 18,915
  • 3
  • 47
  • 72
  • 1
    I wasn't aware that this is in Windows API Code Pack - thanks for pointing this out. – Patrick Klug Sep 29 '11 at 05:38
  • 10
    The CommonOpenFileDialog class only exists on Windows Vista or later, so will throw an exception on older operating systems – Rachel Nov 16 '11 at 14:07
  • 1
    Can you please tell how to reference Windows API Code Pack ? – jeff Nov 27 '13 at 11:06
  • 1
    *The Archive Gallery has been retired.*, or so the link says.. Could [this](https://www.nuget.org/packages/Windows7APICodePack/) be the new place for it? – default Jun 24 '14 at 15:28
  • 1
    The Windows API Code Packs are available via Nuget at:- http://www.nuget.org/packages/Windows7APICodePack-Shell/ and https://www.nuget.org/packages/Windows7APICodePack-Core/ – The Lonely Coder Jan 06 '15 at 09:46
  • 1
    Brilliant! Really was as easy as advertised. I installed just the Shell pack mentioned above and everything worked like a charm. – Karl Hoaglund Oct 17 '15 at 01:26
  • 3
    By the way, the CommonOpenFileDialog class is in the Microsoft.WindowsAPICodePack.Dialogs namespace (took me a while to find it). – morgb Feb 17 '16 at 19:32
  • Is it really advisable to be using something that is no longer available from source (Microsoft), what if they remove the references for this in the newer OSs? dialog wouldn't work anymore and as pointed out by @Rahel its not backwards compatible either. - Not a great final solution but +1 for being interesting solution and i bet lots of people have benefited already. – AltF4_ Oct 12 '17 at 14:57
  • @morgb Oh thanks for telling it... I just opened "Object Browser" in my VS and you know how slow it is :P – Sreenikethan I Oct 31 '17 at 20:30
  • perfect :) And readily available in VS... just searching in NuGet Package Manger for "WindowsAPICodePack" gets many options, such as the examples mentioned. The result is available after selection (after closing the dialog) in the object.FileName property. – Mike M Dec 10 '17 at 02:02
49

You can use FolderBrowserDialogEx - a re-usable derivative of the built-in FolderBrowserDialog. This one allows you to type in a path, even a UNC path. You can also browse for computers or printers with it. Works just like the built-in FBD, but ... better.

(EDIT: I should have pointed out that this dialog can be set to select files or folders. )

Full Source code (one short C# module). Free. MS-Public license.

Code to use it:

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;
}
Cheeso
  • 189,189
  • 101
  • 473
  • 713
  • 7
    Sorry if I offended, it's just frustrating to ask a question and spell out "I want this specific thing, not these other things" and have people cheerfully suggest the not-requested thing. I wanted a file browser dialog, not a folder browser dialog. – OwenP Mar 12 '09 at 16:40
  • 17
    The way the question is worded, it sounds to me like it is asking for a folder picker dialog - is that not the case? Anyway, this is exactly what I was looking for +1 – Tim Oct 20 '11 at 23:25
  • Definitely the best answer so far – Vasil Popov Oct 05 '15 at 12:16
  • CodePlex has been discontinued. The link no longer takes you to where you meant to jump. With this being essentially a link-only answer, the utility of the answer is no longer given. – IInspectable Feb 12 '18 at 11:07
  • 1
    That doesn't change the fact, that the answer still is a link-only answer. Showing how to use code hosted at an off-site resource ceases to be helpful, when that link, too, becomes temporarily or permanently unavailable. The rules are there for a reason, and this contribution is in conflict with those rules. – IInspectable Mar 07 '18 at 00:05
  • unfortunately, I cannot insert the entire internet into this answer. OTOH, maybe you are overreacting? Look at every other answer here; they all reference some external library or runtime, often _without_ a link! ("Google it yourself", I guess) So... it seems to me it is not really problem to include a reference in an answer. In any case, I'm sorry you weren't more delighted with the answer. – Cheeso Mar 07 '18 at 00:10
  • 1
    I looked at [this](https://stackoverflow.com/a/31082/1889329) answer, and it apparently doesn't reference an off-site resource. So *"every other answer"* is clearly wrong. If you feel like I'm overreacting, maybe you should raise an issue over at meta to discuss the rules. I won't. I'll just apply them. – IInspectable Mar 07 '18 at 00:15
38

The Ookii.Dialogs package contains a managed wrapper around the new (Vista-style) folder browser dialog. It also degrades gracefully on older operating systems.

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
Christian Klauser
  • 4,416
  • 3
  • 31
  • 42
  • 2
    Cool, it's BSD-style-licensed open source! – Roman Starkov Jul 30 '10 at 22:08
  • 7
    the only problem is, I won't let me use .net framework client profile as a target. – Kugel Nov 16 '10 at 19:41
  • 2
    Very nice solution. This is in my view THE best answer. Exactly what I was searching since 3 years. – Samuel May 05 '11 at 19:23
  • Unfortunately it has an ugly bug in XP and it is not being updated since 2009. Bug: gibberish in the top row when using "description": http://vidcoder.codeplex.com/workitem/32 – Mark May 24 '12 at 14:22
  • 1
    Another problem with this solution: it does not allow the user to paste a non-existent path. A minor one, comparatively, but still a pity. – Roman Starkov Nov 24 '12 at 16:44
  • 1
    Best **practical** answer for those who want a `OpenFileDialog`-style folder dialog. – aqua May 14 '13 at 01:21
  • The source compile and run without error, but can only run on OS later than Vista. – Lei Yang Jan 03 '14 at 15:52
  • 1
    Works great, even in VS2017 with an F# console application. Just add a refernce to the PresentationFramework and Ookii.Dialogs.Wpf.dll (wherever it is located; I put a copy in my project folder), and then call it with F# code like this: open Ookii.Dialogs.Wpf [] [] let main argv = let dlg = new VistaFolderBrowserDialog() let dlgResult = dlg.ShowDialog() if dlgResult.HasValue && dlgResult.Value then printfn "%s" dlg.SelectedPath |> ignore – Scott Hutchinson Nov 12 '17 at 20:55
29

Better to use the FolderBrowserDialog for that.

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}
Ryan Farley
  • 11,315
  • 4
  • 46
  • 43
  • +1, visual studio's folder browser looking like a file browser is a bad idea – user7116 Feb 02 '09 at 18:49
  • 9
    I am aware that it is *better* to use a FolderBrowserDialog. I'm curious how it was done regardless. The FolderBrowserDialog stinks in many ways anyway; even in Vista it doesn't have the places bar. Funny how if it's better MS has avoided it in 3 VS versions so far. – OwenP Feb 03 '09 at 16:15
  • 24
    The FolderBrowserDialog has many usability issues. I wouldn't consider actually putting it in an application. See my post for a dialog that has much better usability – Scott Wisniewski Feb 05 '09 at 03:13
  • 7
    FolderBrowserDialog does not allow to: - type/paste full paths in the text field at bottom - use "Favorite Links" bar on Vista - use Search on Vista – decasteljau Mar 01 '09 at 19:38
  • 91
    The FolderBrowserDialog is a truly horrible bit of UI. – mackenir May 05 '10 at 12:47
  • 32
    Seriously, people, PLEASE stop putting this annoying dialog into your applications. It has VERY BAD UI as highlighted by earlier comments. – Roman Starkov Jul 30 '10 at 20:46
  • 4
    Sure, FolderBrowserDialog is a piece of crap dialog. I don't like it either. But my answer for the OP was that a dialog meant for selecting a folder, even a badly designed one, was a better route than tricking out the OpenFileDialog to allow only folders to be selected. That would only confuse a typical user IMO (face it, users are stupid). – Ryan Farley Jul 31 '10 at 00:22
  • @Ryan I agree that it's bad to just replace it with another crap dialog, but the Open Folder seems to be official in Vista. Also, http://stackoverflow.com/questions/238177/worst-ui-youve-ever-used/423816#423816 :) – Roman Starkov Aug 13 '10 at 14:01
  • 1
    @romkyns the origin FolderBrowserDialog is WORSE. – Narutokk Aug 02 '11 at 10:21
  • Worse than the dialog is that for most apps it's just one flag (BIF_USENEWUI) to make that abomination bearable, and a rather trivial callback to give it an initial selection. – peterchen Jul 20 '12 at 14:27
  • Just exactly what I need. – Adrian Enriquez Feb 14 '14 at 03:12
  • I have to agree this is not to the point of the question. I also agree I hate the FolderBrowser box, but it doesn't matter... the OP wasn't asking for a comparison. – Mike M Dec 10 '17 at 02:11
23

After hours of searching I found this answer by leetNightShade to a working solution.

There are three things I believe make this solution much better than all the others.

  1. It is simple to use. It only requires you include two files (which can be combined to one anyway) in your project.
  2. It falls back to the standard FolderBrowserDialog when used on XP or older systems.
  3. The author grants permission to use the code for any purpose you deem fit.

    There’s no license as such as you are free to take and do with the code what you will.

Download the code here.

Community
  • 1
  • 1
Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
  • @MattDavis: I confirmed that it works on .NET Framework 4.0 (both Standard and Client Profile). Just make sure you have both the FolderSelectDialog.cs and Reflector.cs added to your project. One thing though... are you running on Windows 8? I tested on a Win7 computer. – Alex Essilfie Nov 27 '13 at 15:10
  • @Alex Essilfie, you are correct. I must've done something wrong in pulling it into my project. I'll delete my earlier comment for clarity. – Matt Davis Nov 27 '13 at 17:27
  • Ran through multiple options and thinking this one is the best. Recommending. – Jaded Oct 10 '14 at 09:27
  • Worked in windows 10 for me. Good simple solution – David Wilton Jun 09 '16 at 01:47
  • have to respect the failover in older systems – Mike M Dec 10 '17 at 02:12
  • 1
    It should be mentioned that the Reflector class is from [Front-End for Dosbox](http://code.google.com/p/fed/) and this is GPL v2. So it *has* license restrictions. – Gerd K Mar 31 '22 at 13:35
  • @GerdK Well, you're right in pointing out that the Reflector class is from [FED](https://code.google.com/p/fed). However, examining both source codes (and the article linked), it appears that apart from that one file, the implementations are sufficiently different to warrant this author claiming it is his own and not a rip-off of FED. The wrinkle though is that the date modified in the linked code is also earlier than those in FED. So although the article cites FED, it's unclear which came first. Regardless, I leave it to you to decide which one to use and the license restrictions that apply. – Alex Essilfie Mar 31 '22 at 17:41
18

OK, let me try to connect the first dot ;-) Playing a little bit with Spy++ or Winspector shows that the Folder textbox in the VS Project Location is a customization of the standard dialog. It's not the same field as the filename textbox in a standard file dialog such as the one in Notepad.

From there on, I figure, VS hides the filename and filetype textboxes/comboboxes and uses a custom dialog template to add its own part in the bottom of the dialog.

EDIT: Here's an example of such customization and how to do it (in Win32. not .NET):

m_ofn is the OPENFILENAME struct that underlies the file dialog. Add these 2 lines:

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

where IDD_FILEDIALOG_IMPORTXLIFF is a custom dialog template that will be added in the bottom of the dialog. See the part in red below. alt text
(source: apptranslator.com)

In this case, the customized part is only a label + an hyperlink but it could be any dialog. It could contain an OK button that would let us validate folder only selection.

But how we would get rid of some of the controls in the standard part of the dialog, I don't know.

More detail in this MSDN article.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Serge Wautier
  • 21,494
  • 13
  • 69
  • 110
  • 1
    That sounds like some explanations I've heard in the past, but I've never seen a demonstration of the concept. Are there walkthroughs in MSDN documentation about doing so? – OwenP Feb 03 '09 at 16:12
17

Exact Audio Copy works this way on Windows XP. The standard file open dialog is shown, but the filename field contains the text "Filename will be ignored".

Just guessing here, but I suspect the string is injected into the combo box edit control every time a significant change is made to the dialog. As long as the field isn't blank, and the dialog flags are set to not check the existence of the file, the dialog can be closed normally.

Edit: this is much easier than I thought. Here's the code in C++/MFC, you can translate it to the environment of your choice.

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

Edit 2: This should be the translation to C#, but I'm not fluent in C# so don't shoot me if it doesn't work.

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
}

Edit 3: Finally looked at the actual dialog in question, in Visual Studio 2005 (I didn't have access to it earlier). It is not the standard file open dialog! If you inspect the windows in Spy++ and compare them to a standard file open, you'll see that the structure and class names don't match. When you look closely, you can also spot some differences between the contents of the dialogs. My conclusion is that Microsoft completely replaced the standard dialog in Visual Studio to give it this capability. My solution or something similar will be as close as you can get, unless you're willing to code your own from scratch.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
10

You can subclass the file dialog and gain access to all its controls. Each has an identifier that can be used to obtain its window handle. You can then show and hide them, get messages from them about selection changes etc. etc. It all depends how much effort you want to take.

We did ours using WTL class support and customized the file dialog to include a custom places bar and plug-in COM views.

MSDN provides information on how to do this using Win32, this CodeProject article includes an example, and this CodeProject article provides a .NET example.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
10

You can use code like this

  • The filter is hide files
  • The filename is hide first text

To advanced hide of textbox for filename you need to look at OpenFileDialogEx

The code:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}
Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
Avram
  • 4,267
  • 33
  • 40
5

I assume you're on Vista using VS2008? In that case I think that the FOS_PICKFOLDERS option is being used when calling the Vista file dialog IFileDialog. I'm afraid that in .NET code this would involve plenty of gnarly P/Invoke interop code to get working.

Duncan Smart
  • 31,172
  • 10
  • 68
  • 70
3

First Solution

I developed this as a cleaned up version of .NET Win 7-style folder select dialog by Bill Seddon of lyquidity.com (I have no affiliation). (I learned of his code from another answer on this page). I wrote my own because his solution requires an additional Reflection class that isn't needed for this focused purpose, uses exception-based flow control, doesn't cache the results of its reflection calls. Note that the nested static VistaDialog class is so that its static reflection variables don't try to get populated if the Show method is never called. It falls back to the pre-Vista dialog if not in a high enough Windows version. Should work in Windows 7, 8, 9, 10 and higher (theoretically).

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

It is used like so in a Windows Form:

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

You can of course play around with its options and what properties it exposes. For example, it allows multiselect in the Vista-style dialog.

Second Solution

Simon Mourier gave an answer that shows how to do the exact same job using interop against the Windows API directly, though his version would have to be supplemented to use the older style dialog if in an older version of Windows. Unfortunately, I hadn't found his post yet when I worked up my solution. Name your poison!

ErikE
  • 48,881
  • 23
  • 151
  • 196
  • Similar usage example to call this fine dialog as a dialog box (e.g. from console-type apps) with empty handle: compiles right out the box: var dialog = new FolderSelectDialog { InitialDirectory = "C:\\", Title = "Select a folder to import music from" }; if (dialog.Show()) { string myFolder = dialog.FileName; } – Philm Jun 11 '16 at 02:21
  • Note: My usage example as a comment is difficult to read, therefore: Most important change to original usage "example": Use a comma between InitialDirectory and Title.. – Philm Jun 11 '16 at 17:24
1

Try this one from Codeproject (credit to Nitron):

I think it's the same dialog you're talking about - maybe it would help if you add a screenshot?

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;
}
demoncodemonkey
  • 11,730
  • 10
  • 61
  • 103
  • http://images.google.com/images?hl=en&q=OpenFileDialog&btnG=Search+Images&gbv=2 Do research when uncertain. I described what I wanted, and FolderBrowserDialog has already been disqualified as an answer. – OwenP Feb 03 '09 at 16:13
  • "I am aware of the FolderBrowserDialog, but I've never really liked that dialog. It starts too small and doesn't let me take advantage of being able to type a path." Do some research yourself - you can type a path in there. Anyway I think it's a bit of an ambiguous question, so good luck with it. – demoncodemonkey Feb 03 '09 at 16:51
  • @demoncodemonkey: You can not type in a part of the path and then navigate to the target you want. By far not as convenient as the options the FileOpenDialog offers. – Treb Feb 03 '09 at 20:38
1

The Ookii Dialogs for WPF library has a class that provides an implementation of a folder browser dialog for WPF.

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

Ookii Folder Browser Dialog

There's also a version that works with Windows Forms.

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
1

On Vista you can use IFileDialog with FOS_PICKFOLDERS option set. That will cause display of OpenFileDialog-like window where you can select folders:

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

For older Windows you can always resort to trick with selecting any file in folder.

Working example that works on .NET Framework 2.0 and later can be found here.

Josip Medved
  • 3,631
  • 1
  • 28
  • 36
1

You can use code like this

The filter is empty string. The filename is AnyName but not blank

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;
lantran
  • 21
  • 2
  • 6
    I know this is an old post, but for the sake of anyone who wants to try this out, it doesn't actually work unless the directory you want to open has absolutely no child directories. So if I want to let my user browse to a folder and select it, and populate the folder path in some text box, the user could never select C:\SomeParentDir if the directory C:\SomeParentDir\SomeChildDir exists, because selecting "Open" just brings you to the child directory. – Jim May 21 '12 at 17:16
  • Nice try.. but this results in terrible UI as "AnyFile" in the textbox is just waiting for the user to override its text.. other than that the user can also select files - not good enough. but nice try.. – G.Y Oct 27 '14 at 17:46
-1

I know the question was on configuration of OpenFileDialog but seeing that Google brought me here i may as well point out that if you are ONLY looking for folders you should be using a FolderBrowserDialog Instead as answered by another SO question below

How to specify path using open file dialog in vb.net?

AltF4_
  • 2,312
  • 5
  • 36
  • 56
  • Misleading. 1) It's **not** the only choice; 2) It's no good choice in most cases; Still it requires the least code, traded by more end-user time spent. – Meow Cat 2012 Nov 08 '19 at 04:05