如何在所选文件夹中打开FolderBrowserDialog?

时间:2009-04-01 13:08:49

标签: .net winforms

我有一个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;
        }

9 个答案:

答案 0 :(得分:19)

如果将RootFolder设置为Environment.SpecialFolder.Desktop,只要路径有效,它就会打开到SelectedFolder。

当您将RootFolder设置为Environment.SpecialFolder.MyComputer时,第一次打开对话框时,它将始终从MyComputer开始,而不是从SelectedFolder路径开始。

如果进行了有效选择,则相同FolderBrowserDialog实例的后续使用将在先前选择的路径中打开。

答案 1 :(得分:10)

从Microsoft帮助FolderBrowserDialog类:

  

通常,在创建新的之后   FolderBrowserDialog,你设置了   RootFolder到哪个位置   开始浏览你可以选择   将SelectedPath设置为绝对值   RootFolder的子目录的路径   最初将被选中。

您是否可能将SelectedPath设置为不等于RootFolder(即我的电脑)子文件夹的位置?这可能会导致它作为呈现的位置潜回到RootFolder。

答案 2 :(得分:9)

将rootfolder设置为

Environment.SpecialFolder.Desktop

它可以按你的意愿工作。

这是实际设置初始选定文件夹的唯一方法。你认为使用

Environment.SpecialFolder.MyComputer

会起作用,但事实并非如此。

答案 3 :(得分:5)

这对我有用:

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

设置SelectedPath属性,而不是RootFolder。

编辑: 这是一个截图,显示Application.StartupPath位于“C:\ LocalDocuments \ Visual Studio 2010 \ Projects \ FolderBrowserDialogTest \ FolderBrowserDialogTest \ bin \ Debug”中,这绝对是桌面目录中的不是

enter image description here

答案 4 :(得分:3)

文件夹浏览器对话框是一个围绕Windows API调用的包装器,它与所有可能的相关路径不匹配(我认为这将是一项艰巨的任务......)这可以使用您自己的类来模仿。在应用程序中生成以下类(添加namespace和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);
    }

然后在设置根文件夹时在调用类中使用以下语法。如果你找到一个接近值,最好检查enum fior,但是如果你不能,那么下面的那个是相当通用的,并允许我很容易地移动到我的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; 
        }
    }

希望有所帮助:)

答案 5 :(得分:2)

我的解决方案,here

我是根据ParkerJay86的this solution编写的。该解决方案适用于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;
            }
        }

答案 6 :(得分:0)

我试图将不存在的文件夹路径分配给SelectedFolder属性。使用有效路径时,根文件夹将失去相关性。如果您未指定SelectedFolder值,则至少有一个Environment.SepcialFolder值就足够了。

即将推出:尝试使用反射动态设置非特殊根文件夹。敬请关注。

答案 7 :(得分:0)

要选择现有路径(没有特殊的文件夹),您必须编写自己的基于树视图的表单。

答案 8 :(得分:0)

我看到这个问题使用:

RootFolder = Environment.SpecialFolder.MyComputer
SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

通过使用该路径的子路径和兄弟分支的硬连线版本,我认为这确实是一种权限。它不适用于C:\ Users [UserID] \ Documents,但它适用于C:\ Users或C:\ Users \ Public \ Documents(即使它不存在,或者在至少它被称为公共文档而不是文档),或C:\ Users \ Default \ Documents(即使它不存在,或者至少它被称为我的文档而不是文档)。

我最终做的是检查SelectedPath是否包含" \ users [UserID]",然后使用Environment.SpecialFolder.Desktop(如果有)和Environment.SpecialFolder.MyComputer,如果它没有'吨。

或许,检查SelectedPath文件夹权限将是一个更好的测试,但这将适用于预期的用例。