是否有可能使用非专用文件夹作为的FolderBrowserDialog的根文件夹?文件夹、有可能、FolderBrowserDialog

2023-09-03 05:34:57 作者:爱笑的智障

FolderBrowserDialog.RootFolder物业被限制在的 Environment.SpecialFolder 枚举。然而,在我的applciation,我们需要显示该对话框,但根本路径必须是可配置的,并且通常是一个自定义文件夹,不涉及任何特殊的文件夹中的枚举。

FolderBrowserDialog.RootFolder Property is restricted to only special folder defined in the Environment.SpecialFolder enumerator. However in my applciation, we need to show this dialog, but the root path needs to be configurable, and is normally a custom folder, not related to any of the special folder in the enumerator.

我怎么能显示与分配给一个自定义文件夹的根文件夹的浏览器?也许这是不可能的RootFolder属性,但有可能有其它方式相同的效果(即用户不能查看或根目录以外的选择)。在这个答案,有人暗示可能使用反射操作是可能的,但没有更新。任何想法,如果这是可能的。NET?

How can I show a folder browser with the root assigned to a custom folder? Maybe it's not possible with RootFolder property, but is it possible to have the same effect by other means (i.e. user can't view or select outside the root folder). In this answer, somebody hinted that it might be possible using reflection manipulation, but there was no update. Any idea if this is possible in .NET?

推荐答案

我写了基于这个解决方案由ParkerJay86 的。该解决方案的工作在Windows 8测试了路径。考虑到你指定的rootFolder应该从驱动器号:\ C:\ ProgramData

I wrote this solution based on this solution by ParkerJay86. The solution worked on Windows 8 with several paths tested. Consider that your specified rootFolder should start with DriveLetter:\ like "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;
    }
}