【问题标题】:How do I open a FolderBrowserDialog at the selected folder?如何在所选文件夹中打开 FolderBrowserDialog?
【发布时间】:2009-04-01 13:08:48
【问题描述】:

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

【问题讨论】:

    标签: .net winforms


    【解决方案1】:

    这对我有用:

    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”中,这绝对是在桌面目录中。 p>

    【讨论】:

    • 这仅在应用程序放置在桌面子文件夹中的某个位置时才有效
    • 我通过添加截图显示它与桌面无关进行编辑。它在其他地方工作正常。
    • 只是为了澄清 Application 是 System.Windows.Forms.Application
    【解决方案2】:

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

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

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

    【讨论】:

    • 这不是我看到的行为。我的 RootFolder 设置为 MyComputer,我可以将 SelectedFolder 设置为“C:\Almo”,它将在那里打开。它不会做的是在“C:\Users\Almo\Desktop”打开,我怀疑这是权限问题。
    • @Almo 将 RootFolder 和 SelectedFolder 设置为 Environment.SpecialFolder.Desktop。然后,假设您以 Almo 身份运行,它应该打开到“C:\Users\Almo\Desktop”。
    • 哇,我把真假搞混了(不要问)。忽略我对 Almo 评论的反对意见。 +1
    【解决方案3】:

    将根文件夹设置为

    Environment.SpecialFolder.Desktop
    

    它应该可以按您的意愿工作。

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

    Environment.SpecialFolder.MyComputer
    

    会起作用,但不会。

    【讨论】:

      【解决方案4】:

      来自 Microsoft 对 FolderBrowserDialog 类的帮助:

      通常,在创建一个新的 FolderBrowserDialog,你设置 RootFolder 到的位置 开始浏览。或者,您可以 将 SelectedPath 设置为绝对 RootFolder 的子文件夹的路径 最初会被选中。

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

      【讨论】:

      • “c:\yadda yadda”路径应该是“我的电脑”的子文件夹,不是吗?
      【解决方案5】:

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

      然后在设置根文件夹时在调用类中使用以下语法。如果你能找到一个接近的值,最好检查一下枚举值,但如果你不能,那么下面的那个是相当通用的,可以让我轻松地通过我的 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; 
              }
          }
      

      希望有帮助:)

      【讨论】:

        【解决方案6】:

        我的解决方案,here

        我根据 ParkerJay86 的 this solution 编写了这个解决方案。该解决方案适用于 Windows 8,并测试了多个路径。考虑到您指定的根文件夹应该以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;
                    }
                }
        

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 即将推出?从 2009 年到 2017 年?
          【解决方案8】:

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

          【讨论】:

          【解决方案9】:

          我看到这个问题使用:

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

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

          我最终做的是检查 SelectedPath 是否包含“\users[UserID]”,如果包含则使用 E​​nvironment.SpecialFolder.Desktop,如果不包含则使用 E​​nvironment.SpecialFolder.MyComputer。

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

          【讨论】:

            猜你喜欢
            • 2012-08-12
            • 1970-01-01
            • 2020-09-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-26
            • 1970-01-01
            • 2020-08-23
            相关资源
            最近更新 更多