How do you configure an OpenFileDialog to select folders?
Asked Answered
F

17

264

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.

Fantasy answered 27/8, 2008 at 19:54 Comment(6)
just a simple solution from codeproject codeproject.com/Articles/44914/… [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";).]Stylopodium
Submit this as an answer, it did the job for my project.Prosopopoeia
@Stylopodium 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 falseIrrelevance
nvm, in powershell setting dialog.CheckFileExists = 0 instead of false solved my issueIrrelevance
Have you tried the Ookii Dialogs for WPF?Legalism
I shared another working answer here: https://mcmap.net/q/81542/-how-add-multiselect-to-this-custom-file-dialogObeah
T
62

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

Tanana answered 5/2, 2009 at 2:58 Comment(13)
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.Fantasy
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'.Heidt
@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).Donegal
I think simply using the Microsoft Windows API Pack is a better solution: #31559Cerelia
@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.Tanana
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.Inoperative
+1 for a very good (in spite of buggy library navigation). I'd recommend you put all code in one file or provide a pre-built solution to make usage simpler.Emulsion
I downloaded the code(zip) and found .h(C) file in, and compiled with error such as cannot open include file 'sal.h'.Deflected
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. i.imgur.com/wPa986V.png I am on windows 7.Bilocular
This solution does not work on VS2010 and VS2017 either!Alderman
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.Tanana
The WindowsCodePack through built-in NuGet is so straightforward and also seems well-used I think it must be the best answer.Sherer
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 issuesForetopmast
E
53

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.

Electrodynamic answered 14/2, 2011 at 23:51 Comment(10)
I wasn't aware that this is in Windows API Code Pack - thanks for pointing this out.Cerelia
The CommonOpenFileDialog class only exists on Windows Vista or later, so will throw an exception on older operating systemsChalcidice
Can you please tell how to reference Windows API Code Pack ?Aery
The Archive Gallery has been retired., or so the link says.. Could this be the new place for it?Graffito
The Windows API Code Packs are available via Nuget at:- nuget.org/packages/Windows7APICodePack-Shell and nuget.org/packages/Windows7APICodePack-CoreCascabel
Brilliant! Really was as easy as advertised. I installed just the Shell pack mentioned above and everything worked like a charm.Spiel
By the way, the CommonOpenFileDialog class is in the Microsoft.WindowsAPICodePack.Dialogs namespace (took me a while to find it).Raceme
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.Shanly
@Raceme Oh thanks for telling it... I just opened "Object Browser" in my VS and you know how slow it is :PWarship
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.Sherer
F
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;
}
Farthest answered 9/3, 2009 at 5:2 Comment(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.Fantasy
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 +1Gummite
Definitely the best answer so farCatechol
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.Gymnasium
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.Gymnasium
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.Farthest
I looked at this 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.Gymnasium
R
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.

Rankins answered 4/2, 2009 at 12:34 Comment(8)
Cool, it's BSD-style-licensed open source!Comment
the only problem is, I won't let me use .net framework client profile as a target.Bendy
Very nice solution. This is in my view THE best answer. Exactly what I was searching since 3 years.Combust
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": vidcoder.codeplex.com/workitem/32Blancheblanchette
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.Comment
Best practical answer for those who want a OpenFileDialog-style folder dialog.Inoperative
The source compile and run without error, but can only run on OS later than Vista.Deflected
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 [<System.STAThread>] [<EntryPoint>] let main argv = let dlg = new VistaFolderBrowserDialog() let dlgResult = dlg.ShowDialog() if dlgResult.HasValue && dlgResult.Value then printfn "%s" dlg.SelectedPath |> ignoreLeavelle
S
28

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);
    }
}
Sterol answered 27/8, 2008 at 19:59 Comment(12)
+1, visual studio's folder browser looking like a file browser is a bad ideaBabylonia
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.Fantasy
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 usabilityTanana
FolderBrowserDialog does not allow to: - type/paste full paths in the text field at bottom - use "Favorite Links" bar on Vista - use Search on VistaCassiecassil
The FolderBrowserDialog is a truly horrible bit of UI.Unspoken
Seriously, people, PLEASE stop putting this annoying dialog into your applications. It has VERY BAD UI as highlighted by earlier comments.Comment
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).Sterol
@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, stackoverflow.com/questions/238177/worst-ui-youve-ever-used/… :)Comment
@romkyns the origin FolderBrowserDialog is WORSE.Waistline
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.Ealasaid
Just exactly what I need.Vanguard
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.Sherer
E
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.

Emulsion answered 9/6, 2013 at 15:3 Comment(7)
@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.Emulsion
@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.Nolly
Ran through multiple options and thinking this one is the best. Recommending.Slam
Worked in windows 10 for me. Good simple solutionLeftward
have to respect the failover in older systemsSherer
It should be mentioned that the Reflector class is from Front-End for Dosbox and this is GPL v2. So it has license restrictions.Minutia
@GerdK Well, you're right in pointing out that the Reflector class is from 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.Emulsion
G
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.

Ghent answered 3/2, 2009 at 8:2 Comment(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?Fantasy
U
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.

Unfamiliar answered 4/2, 2009 at 4:10 Comment(0)
A
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.

Amyotonia answered 3/2, 2009 at 22:4 Comment(0)
L
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;
}
Lixivium answered 5/2, 2009 at 2:9 Comment(2)
Simple and is what I need for Windows 7+Neurophysiology
Also OFN_NOVALIDATE is required in flagsGrist
P
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.

Picturesque answered 28/8, 2008 at 1:32 Comment(1)
Vista-specific; I first saw this on VS 2003 on Windows XP.Fantasy
E
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!

Etienne answered 20/11, 2015 at 21:27 Comment(2)
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; }Desperate
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..Desperate
C
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;
}
Chaqueta answered 3/2, 2009 at 8:39 Comment(3)
images.google.com/… Do research when uncertain. I described what I wanted, and FolderBrowserDialog has already been disqualified as an answer.Fantasy
"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.Chaqueta
@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.Oahu
H
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.

Hetman answered 4/1, 2012 at 1:18 Comment(0)
E
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;
Evermore answered 19/3, 2012 at 2:42 Comment(2)
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.Vase
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..Hotchpotch
L
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.

Legalism answered 4/10, 2018 at 3:31 Comment(0)
S
-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?

Shanly answered 12/10, 2017 at 15:4 Comment(1)
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.Telefilm

© 2022 - 2024 — McMap. All rights reserved.