Как открыть FolderBrowserDialog в выбранной папке? - PullRequest
25 голосов
/ 01 апреля 2009

У меня есть 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 ]

19 голосов
/ 09 марта 2010

Если вы установите RootFolder в Environment.SpecialFolder.Desktop, то он будет открыт для SelectedFolder, пока путь действителен.

Когда вы устанавливаете RootFolder в Environment.SpecialFolder.MyComputer, то при первом открытии диалогового окна он всегда начинается с MyComputer, а не с пути SelectedFolder.

Если сделан правильный выбор, то последующее использование того же экземпляра FolderBrowserDialog откроется по ранее выбранному пути.

10 голосов
/ 01 апреля 2009

Из справки Microsoft для класса FolderBrowserDialog:

Как правило, после создания нового FolderBrowserDialog, вы устанавливаете RootFolder к месту, из которого начать просмотр. При желании вы можете установить SelectedPath в абсолют путь к подпапке RootFolder, который будет изначально выбран.

Возможно, вы устанавливаете SelectedPath в местоположение, которое не соответствует подпапке RootFolder (т.е. Мой компьютер)? Это, вероятно, заставит его вернуться к RootFolder в качестве представленного местоположения.

9 голосов
/ 01 марта 2012

Установить корневую папку на

Environment.SpecialFolder.Desktop

и должно работать как хочешь.

Это единственный способ установить исходную выбранную папку. Вы бы подумали, используя

Environment.SpecialFolder.MyComputer

будет работать, но это не так.

5 голосов
/ 12 сентября 2012

Это работает для меня:

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.

EDIT: Вот снимок экрана, показывающий Application.StartupPath, находящийся в "C: \ LocalDocuments \ Visual Studio 2010 \ Projects \ FolderBrowserDialogTest \ FolderBrowserDialogTest \ bin \ Debug", который наиболее определенно не в каталоге Desktop.

enter image description here

3 голосов
/ 03 апреля 2009

Диалоговое окно folderbrowser - это оболочка для вызова API Windows, которая не соответствует всем возможным возможным путям (я полагаю, это будет непростая задача ...), хотя это можно имитировать, используя ваш собственный класс. Создайте следующий класс внутри вашего приложения (добавив пространство имен и 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; 
        }
    }

Надеюсь, это поможет:)

2 голосов
/ 18 октября 2012

Мое решение, здесь

Я написал это решение на основе этого решения от 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;
            }
        }
0 голосов
/ 15 сентября 2017

Я видел эту проблему, используя:

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

Играя с зашитыми версиями подпутей и дочерних веток этого пути, я решил, что это действительно проблема с разрешениями. Он не работает с C: \ Users [UserID] \ Documents, но отлично работает с C: \ Users или C: \ Users \ Public \ Documents (даже если он не существует или, по крайней мере, называется Public Документы вместо документов) или C: \ Users \ Default \ Documents (даже если он не существует или, по крайней мере, называется «Мои документы вместо документов»).

В итоге я проверил, содержит ли SelectedPath «\ users [UserID]», затем с помощью Environment.SpecialFolder.Desktop, если это было сделано, и Environment.SpecialFolder.MyComputer, если этого не произошло.

Вероятно, проверка разрешений для папки SelectedPath будет лучшим тестом, но это подойдет для ожидаемых вариантов использования.

0 голосов
/ 23 октября 2010

Чтобы выбрать существующий путь (без специальных папок ...), вы должны написать собственную форму на основе дерева.

0 голосов
/ 20 сентября 2009

Я пытался назначить несуществующий путь к папке для свойства SelectedFolder. Когда вы используете правильный путь, корневая папка теряет актуальность. Если вы не присваиваете значение SelectedFolder, вам будет достаточно хотя бы одного из значений Environment.SepcialFolder.

СКОРО: Пытается использовать отражение для динамической установки нестандартной корневой папки. Оставайтесь в курсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...