How do I open a FolderBrowserDialog at the selected folder?

后端 未结 9 1892
深忆病人
深忆病人 2020-12-15 18:00

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

相关标签:
9条回答
  • 2020-12-15 18:06

    From the Microsoft help for FolderBrowserDialog class:

    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.

    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.

    0 讨论(0)
  • 2020-12-15 18:07

    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)

    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.

    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 :)

    0 讨论(0)
  • 2020-12-15 18:11

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

    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.

    Probably, checking the SelectedPath folder permissions would be a better test, but this will do for the expected use cases.

    0 讨论(0)
  • 2020-12-15 18:19

    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.

    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 not in the Desktop directory.

    enter image description here

    0 讨论(0)
  • 2020-12-15 18:21

    If you set RootFolder to Environment.SpecialFolder.Desktop then it will open to the SelectedFolder as long as the path is valid.

    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.

    If a valid selection is made, then subsequent uses of the same FolderBrowserDialog instance will open at the previously selected path.

    0 讨论(0)
  • 2020-12-15 18:22

    I was trying to assign a non-existent folder path to the SelectedFolder property. When you use a valid path, the root folder loses relevance. When you don't assign a SelectedFolder value, at least one of the Environment.SepcialFolder values will suffice.

    COMING SOON: Attempts at using reflection to dynamically set a non-special root folder. Stay tuned.

    0 讨论(0)
提交回复
热议问题