views:

10850

answers:

11

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.

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.

+6  A: 

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
+1, visual studio's folder browser looking like a file browser is a bad idea
sixlettervariables
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
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
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
The FolderBrowserDialog is a truly horrible bit of UI.
mackenir
Seriously, people, PLEASE stop putting this annoying dialog into your applications. It has VERY BAD UI as highlighted by earlier comments.
romkyns
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
@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 :)
romkyns
+2  A: 

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
Vista-specific; I first saw this on VS 2003 on Windows XP.
OwenP
+5  A: 
Serge - appTranslator
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
A: 

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
OwenP
"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
@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
+4  A: 

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
+5  A: 

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
+5  A: 

The Ookii.Dialogs package contains a managed wrapper around the new folder browser dialog.

SealedSun
Cool, it's BSD-style-licensed open source!
romkyns
+2  A: 

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

Avram
+4  A: 

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 it's AcceptFiles value to false, then it operates in only accept folder mode.

You can download the source for it here:

http://www.transactor.com/downloads/OpenFileOrFolderDialog.zip

If you run into any issues, want more information about how it works, or want to contribute changes, send me an email message to:

[email protected]

Scott Wisniewski
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
I can try, but it might be a few days. I'll probably put it up on my blog. I'll let you know when it's up.
Scott Wisniewski
Your site checks the referrer, so the direct link does not work.
Don Reba
This link from one of the blogs seems to work: http://www.specbug.com/storage/OpenFileOrFolderDialog.zip
DGGenuine
Links are all broken now :(
thekidder
I've fixed the link. Please try http://www.transactor.com/downloads/OpenFileOrFolderDialog.zip.
Scott Wisniewski
+1  A: 
Cheeso
That's a folder browser dialog, not a file browser dialog. Congratulations for not reading!
OwenP
Congratulations for being snide! It does files+folders.
Cheeso
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
A: 

In case everyone missed it, the OOKII library mentioned above by SealedSun wraps the Vista style Folder Browser beautifully, and reverts to older dialog style in WinXP.

http://www.ookii.org/software/dialogs/

Tim