.net 如何在所选文件夹中打开 FolderBrowserDialog?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/705409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I open a FolderBrowserDialog at the selected folder?
提问by ProfK
I have a FolderBrowserDialog, displayed with code shown below. However, it keeps opening with 'Computer', i.e. the root of the folder tree, selected. How do I get it to open on the selected folder?
我有一个 FolderBrowserDialog,显示的代码如下所示。但是,它会一直打开并选择“计算机”,即文件夹树的根目录。如何让它在选定的文件夹上打开?
var folderBrowser = new FolderBrowserDialog();
folderBrowser.Description = "Select Chase 6 Installation Folder";
folderBrowser.RootFolder = Environment.SpecialFolder.MyComputer;
folderBrowser.ShowNewFolderButton = false;
if (Directory.Exists(Properties.Settings.Default.defaultChasePath))
{
string x = Properties.Settings.Default.defaultChasePath;
folderBrowser.SelectedPath = x;
}
if (folderBrowser.ShowDialog(this) == DialogResult.OK)
{
chasePathtext.Text = folderBrowser.SelectedPath;
}
采纳答案by ProfK
I was trying to assign a non-existent folder path to the SelectedFolderproperty. When you use a valid path, the root folder loses relevance. When you don't assign a SelectedFoldervalue, at least one of the Environment.SepcialFoldervalues will suffice.
我试图为该SelectedFolder属性分配一个不存在的文件夹路径。当您使用有效路径时,根文件夹将失去相关性。当您不分配SelectedFolder值时,至少有一个Environment.SepcialFolder值就足够了。
COMING SOON: Attempts at using reflection to dynamically set a non-special root folder. Stay tuned.
即将推出:尝试使用反射动态设置非特殊根文件夹。敬请关注。
回答by Preston McCormick
If you set RootFolder to Environment.SpecialFolder.Desktop then it will open to the SelectedFolder as long as the path is valid.
如果您将 RootFolder 设置为 Environment.SpecialFolder.Desktop,那么只要路径有效,它就会打开到 SelectedFolder。
When you set RootFolder to Environment.SpecialFolder.MyComputer, then the first time the dialog opens, it will always start at MyComputer, not the SelectedFolder path.
当您将 RootFolder 设置为 Environment.SpecialFolder.MyComputer 时,对话框第一次打开时,它将始终从 MyComputer 开始,而不是 SelectedFolder 路径。
If a valid selection is made, then subsequent uses of the same FolderBrowserDialog instance will open at the previously selected path.
如果进行了有效选择,则相同 FolderBrowserDialog 实例的后续使用将在先前选择的路径上打开。
回答by Lazarus
From the Microsoft help for FolderBrowserDialog class:
来自 FolderBrowserDialog 类的 Microsoft 帮助:
Typically, after creating a new FolderBrowserDialog, you set the RootFolder to the location from which to start browsing. Optionally, you can set the SelectedPath to an absolute path of a subfolder of RootFolder that will initially be selected.
通常,在创建新的 FolderBrowserDialog 后,您将 RootFolder 设置为开始浏览的位置。或者,您可以将 SelectedPath 设置为初始选择的 RootFolder 子文件夹的绝对路径。
Are you possibly setting the SelectedPath to a location that doesn't equate to a subfolder of RootFolder (i.e. My Computer)? That would probably cause it to dive back to the RootFolder as the presented location.
您是否可能将 SelectedPath 设置为不等同于 RootFolder 的子文件夹(即我的电脑)的位置?这可能会导致它返回到 RootFolder 作为显示的位置。
回答by Richard
Set rootfolder to
将根文件夹设置为
Environment.SpecialFolder.Desktop
and it should work as you want.
它应该可以如你所愿。
It is the only way to actually set the initial selected folder. You'd think using
这是实际设置初始选定文件夹的唯一方法。你会认为使用
Environment.SpecialFolder.MyComputer
would work, but it doesn't.
会起作用,但不会。
回答by pennyrave
This works for me:
这对我有用:
FolderBrowserDialog diag = new FolderBrowserDialog();
diag.Description = "Select a folder in which to save your workspace...";
diag.SelectedPath = Application.StartupPath;
if (DialogResult.OK == diag.ShowDialog())
{
// do something here...
}
Set the SelectedPath property, not RootFolder.
设置 SelectedPath 属性,而不是 RootFolder。
EDIT: Here's a screenshot showing the Application.StartupPath being in "C:\LocalDocuments\Visual Studio 2010\Projects\FolderBrowserDialogTest\FolderBrowserDialogTest\bin\Debug", which is most definitely notin the Desktop directory.
编辑:这是显示 Application.StartupPath 位于“C:\LocalDocuments\Visual Studio 2010\Projects\FolderBrowserDialogTest\FolderBrowserDialogTest\bin\Debug”中的屏幕截图,它绝对不在桌面目录中。


回答by Matrim
The folderbrowser dialog is a wrapper around a windows API call that does not match all the relevant paths possible ( I suppose that would be an uphill task..) this can be mimicked using your own class though. Generate the following class inside your application (adding namespace and System.Reflection)
folderbrowser 对话框是 Windows API 调用的包装器,它与所有可能的相关路径都不匹配(我认为这将是一项艰巨的任务..),不过可以使用您自己的类来模拟。在您的应用程序中生成以下类(添加命名空间和 System.Reflection)
public class RootSetter
{
[Flags()]
public enum CsIdl
{
Desktop = 0x0000, // Desktop
Internet = 0x0001, // Internet Explorer (icon on desktop)
Programs = 0x0002, // Start Menu\Programs
Controls = 0x0003, // My Computer\Control Panel
Printers = 0x0004, // My Computer\Printers
Personal = 0x0005, // My Documents
Favorites = 0x0006, // user name\Favorites
Startup = 0x0007, // Start Menu\Programs\Startup
Recent = 0x0008, // user name\Recent
SendTo = 0x0009, // user name\SendTo
BitBucket = 0x000a, // desktop\Recycle Bin
StartMenu = 0x000b, // user name\Start Menu
MyDocuments = 0x000c, // logical "My Documents" desktop icon
MyMusic = 0x000d, // "My Music" folder
MyVideo = 0x000e, // "My Videos" folder
DesktopDirectory = 0x0010, // user name\Desktop
Drives = 0x0011, // My Computer
Network = 0x0012, // Network Neighborhood (My Network Places)
Nethood = 0x0013, // user name\nethood
Fonts = 0x0014, // windows\fonts
Templates = 0x0015,
CommonStartMenu = 0x0016, // All Users\Start Menu
CommonPrograms = 0x0017, // All Users\Start Menu\Programs
CommonStartup = 0x0018, // All Users\Startup
CommonDesktopDirectory = 0x0019, // All Users\Desktop
AppData = 0x001a, // user name\Application Data
PrintHood = 0x001b, // user name\PrintHood
LocalAppData = 0x001c, // user name\Local Settings\Applicaiton Data (non roaming)
AltStartup = 0x001d, // non localized startup
CommonAltStartup = 0x001e, // non localized common startup
CommonFavorites = 0x001f,
InternetCache = 0x0020,
Cookies = 0x0021,
History = 0x0022,
CommonAppdata = 0x0023, // All Users\Application Data
Windows = 0x0024, // GetWindowsDirectory()
System = 0x0025, // GetSystemDirectory()
ProgramFiles = 0x0026, // C:\Program Files
MyPictures = 0x0027, // C:\Program Files\My Pictures
Profile = 0x0028, // USERPROFILE
SystemX86 = 0x0029, // x86 system directory on RISC
ProgramFilesX86 = 0x002a, // x86 C:\Program Files on RISC
ProgramFilesCommon = 0x002b, // C:\Program Files\Common
ProgramFilesCommonx86 = 0x002c, // x86 Program Files\Common on RISC
CommonTemplates = 0x002d, // All Users\Templates
CommonDocuments = 0x002e, // All Users\Documents
CommonAdminTools = 0x002f, // All Users\Start Menu\Programs\Administrative Tools
AdminTools = 0x0030, // user name\Start Menu\Programs\Administrative Tools
Connections = 0x0031, // Network and Dial-up Connections
CommonMusic = 0x0035, // All Users\My Music
CommonPictures = 0x0036, // All Users\My Pictures
CommonVideo = 0x0037, // All Users\My Video
Resources = 0x0038, // Resource Direcotry
ResourcesLocalized = 0x0039, // Localized Resource Direcotry
CommonOemLinks = 0x003a, // Links to All Users OEM specific apps
CdBurnArea = 0x003b, // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
ComputersNearMe = 0x003d, // Computers Near Me (computered from Workgroup membership)
FlagCreate = 0x8000, // combine with CSIDL_ value to force folder creation in SHGetFolderPath()
FlagDontVerify = 0x4000, // combine with CSIDL_ value to return an unverified folder path
FlagNoAlias = 0x1000, // combine with CSIDL_ value to insure non-alias versions of the pidl
FlagPerUserInit = 0x0800, // combine with CSIDL_ value to indicate per-user init (eg. upgrade)
FlagMask = 0xFF00, // mask for all possible flag values
}
public static void SetRootFolder(System.Windows.Forms.FolderBrowserDialog fbd, CsIdl csidl)
{
Type t = fbd.GetType();
FieldInfo fi = t.GetField("rootFolder", BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(fbd, (System.Environment.SpecialFolder)csidl);
}
and then inside your calling class when setting the root folder use the following syntax. It would be better to check the enum fior a close value should you find one but if you cannto then the one below is fairly generic and allows me to move thorugh my C drive easily enough.
然后在设置根文件夹时在您的调用类中使用以下语法。如果你找到一个接近的值,最好检查枚举值,但如果你不能,那么下面的一个是相当通用的,让我可以轻松地通过我的 C 驱动器。
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowser = new FolderBrowserDialog();
folderBrowser.Description = "Select Chase 6 Installation Folder";
folderBrowser.RootFolder = Environment.SpecialFolder.ProgramFiles;
folderBrowser.ShowNewFolderButton = false;
if (Directory.Exists(Properties.Settings.Default.defaultChasePath))
{
string x = Properties.Settings.Default.defaultChasePath;
//Use API Flag to set correct path, following tahter a catch all better to check
//enum for full list
RootSetter.SetRootFolder(folderBrowser, RootSetter.CsIdl.FlagDontVerify);
folderBrowser.SelectedPath = x;
}
if (folderBrowser.ShowDialog(this) == DialogResult.OK)
{
string huz = folderBrowser.SelectedPath;
}
}
Hope that helps :)
希望有帮助:)
回答by Mohsen Afshin
My solution, here
我的解决方案,在这里
I wrote this solution based on this solutionby ParkerJay86. The solution worked on Windows 8 with several paths tested. Consider that your specified rootFolder should start with DriveLetter:\like "C:\ProgramData"
我根据ParkerJay86 的这个解决方案编写了这个解决方案。该解决方案适用于 Windows 8,并测试了多个路径。考虑您指定的 rootFolder 应该以DriveLetter:\“ C:\ProgramData”开头
private void browseFolder_Click(object sender, EventArgs e)
{
String selectedPath;
if (ShowFBD("C:\", "Please Select a folder", out selectedPath))
{
MessageBox.Show(selectedPath);
}
}
public bool ShowFBD(String rootFolder, String title, out String selectedPath)
{
var shellType = Type.GetTypeFromProgID("Shell.Application");
var shell = Activator.CreateInstance(shellType);
var result = shellType.InvokeMember("BrowseForFolder", BindingFlags.InvokeMethod, null, shell, new object[] { 0, title, 0, rootFolder });
if (result == null)
{
selectedPath = "";
return false;
}
else
{
StringBuilder sb = new StringBuilder();
while (result != null)
{
var folderName = result.GetType().InvokeMember("Title", BindingFlags.GetProperty, null, result, null).ToString();
sb.Insert(0, String.Format("{0}\", folderName));
result = result.GetType().InvokeMember("ParentFolder", BindingFlags.GetProperty, null, result, null);
}
selectedPath = sb.ToString();
selectedPath = Regex.Replace(selectedPath, @"Desktop\Computer\.*\(\w:\)\", rootFolder.Substring(0, 3));
return true;
}
}
回答by B H
I was seeing this problem using:
我看到这个问题使用:
RootFolder = Environment.SpecialFolder.MyComputer
SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
By playing around with hard-wired versions of that path's subpaths and sibling branches, I decided this really is a permissions thing. It doesn't work with C:\Users[UserID]\Documents, but it works fine with C:\Users, or C:\Users\Public\Documents (even though that doesn't exist or, at least it's called Public Documents instead of Documents), or C:\Users\Default\Documents (even though that doesn't exist or, at least it's called My Documents instead of Documents).
通过使用该路径的子路径和兄弟分支的硬接线版本,我决定这确实是一个权限问题。它不适用于 C:\Users[UserID]\Documents,但它适用于 C:\Users 或 C:\Users\Public\Documents(即使它不存在,或者至少它被称为 Public Documents 而不是 Documents),或 C:\Users\Default\Documents(即使它不存在,或者至少它被称为我的文档而不是文档)。
What I ended up doing was checking whether the SelectedPath contains "\users[UserID]", then using Environment.SpecialFolder.Desktop if it did and Environment.SpecialFolder.MyComputer if it didn't.
我最终做的是检查 SelectedPath 是否包含“\users[UserID]”,然后使用 Environment.SpecialFolder.Desktop(如果包含)和 Environment.SpecialFolder.MyComputer(如果没有)。
Probably, checking the SelectedPath folder permissions would be a better test, but this will do for the expected use cases.
可能,检查 SelectedPath 文件夹权限会是一个更好的测试,但这将适用于预期的用例。
回答by czlowiek
To select existing path (no special f...ng folders) you must write own treeview based form.
要选择现有路径(没有特殊的 f...ng 文件夹),您必须编写自己的基于树视图的表单。

