.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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:27:14  来源:igfitidea点击:

How do I open a FolderBrowserDialog at the selected folder?

.netwinforms

提问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”中的屏幕截图,它绝对不在桌面目录中。

enter image description here

在此处输入图片说明

回答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 文件夹),您必须编写自己的基于树视图的表单。