在VS。净,当你选择一个文件夹,用于一个项目,一个对话,这看起来像一个OpenFileDialog或SaveFileDialog显示,但是设立仅接受的文件夹。自从我已经看到这我一直想知道它是如何做。我知道FolderBrowserDialog,但我从来没有真的很喜欢这个对话。它开始太小,并且不让我利用能够型的道路。

我几乎可以肯定,现在没有一种方法来这样做。净,但是我只是好奇你如何做到这一点从不受管理的代码。短期的重新实现完全的对话,从头开始,你如何修改的对话,以有这样的行为?

我还想重申,我知道FolderBrowserDialog但有时候我不喜欢用它,除了真正的好奇如何配置一个对话以这种方式。告诉我要的只是使用FolderBrowserDialog帮助我保持一致的用户界面的经验,但不能满足我的好奇心,所以它不会计为一个答案。

这不是一个Vista具体的事;我已经看到这一对话由于VS。净2003年,因此它是可行的,在Win2k和WinXP.这是下一个"我想知道的正确方法这样做"的问题,并更加一个"我是好奇的关于这一点,因为我第一个想做到这一点,在VS2003年"的问题。我的理解是,Vista的对话文件有一个选项,要做到这一点,但它已经在工作XP所以我知道他们做的 的东西 来获得它的工作。Vista的具体答案是不是答案,因为Vista不存在这个问题的上下文。

更新:我接受斯科特*维斯涅夫斯基的答案,因为它带有一个工作样,但我认为,塞尔值得信贷,用于向该对话定制(这是无可否认的令人讨厌。净但它 工作)和马赎金搞清楚,MS可能推出一个自定义的对话对于这一任务。

有帮助吗?

解决方案

我有一对话,我写了一个称为OpenFileOrFolder对话,允许你打开文件夹或文件。

如果你设置其AcceptFiles值的虚假的,那么它的工作中仅仅接受的文件夹模式。

你可以下载源从审查这里

其他提示

有窗户代码组。它有很多的外壳有关的东西,包括 CommonOpenFileDialog 类(在 Microsoft.WindowsAPICodePack.Dialogs namespace).这是一个完美的解决方案-通常开放的对话只有文件夹中显示。

这里是一个如何使用它:

CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();

不幸的是Microsoft不再是船舶这个包,但是有几个人已经非正式的二进制文件上传到NuGet.一个例子中可以找到 在这里,.这个包是只是外壳具体的东西。你应该需要它,相同的用户有若干其他的软件包提供更多的功能存在的原始包装。

你可以使用 FolderBrowserDialogEx - 重复使用的衍生物的内在FolderBrowserDialog.这个人允许你在一条路径,即使一个UNC的道路。你也可以浏览的计算机或打印机。就像内森林生物多样性,但是...更好。

(编辑:我应该指出,这种对话可以集中选择的文件或文件夹。)

完整的源代码(一个短C#模块)。免费的。MS-公共许可证。

代码使用它:

var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
dlg1.Description = "Select a folder to extract to:";
dlg1.ShowNewFolderButton = true;
dlg1.ShowEditBox = true;
//dlg1.NewStyle = false;
dlg1.SelectedPath = txtExtractDirectory.Text;
dlg1.ShowFullPathInEditBox = true;
dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;

// Show the FolderBrowserDialog.
DialogResult result = dlg1.ShowDialog();
if (result == DialogResult.OK)
{
    txtExtractDirectory.Text = dlg1.SelectedPath;
}

Ookii.的对话 包含一个管理的包装的新的(Vista式)文件夹,浏览器的对话。它还会降低优雅地在较早的操作系统。

更好地使用FolderBrowserDialog。

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

几小时后搜索,我发现 这个答案 通过 leetNightShade一个工作方案.

有三件事情我相信,使这个解决方案更好于所有其他人。

  1. 它是简单的使用。 它只需要你的包括两个文件(其中可以合并到一个无论如何)在您的项目。
  2. 它回落到标准 FolderBrowserDialog 使用时XP或旧的系统。
  3. 提交人授予许可使用代码,用于任何目的,您认为合适的。

    有没有许可为例如你可以自由采取与代码什么你会的。

下载码 在这里,.

确切的声音复制 这种方式工作,在Windows XP。该标准文件的开放式对话,但是名字中包含的文字"的文件将会被忽略".

只是猜测,但我怀疑是串注入组合框编辑控制的每一次的重大改变了对话。只要领域是不是空白,并将对话的标志设置为不检查文件是否存在,对话可以关闭正常。

编辑: 这是容易得多比我想象的。这里的代码C++/MFC,你可以把它翻译成环境的选择。

CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this);
dlg.DoModal();

编辑2: 这应该是翻译C#但我不能说流利的C#所以不要杀我,如果它不起作用。

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.FileName = "Filename will be ignored";
openFileDialog1.CheckPathExists = true;
openFileDialog1.ShowReadOnly = false;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    // openFileDialog1.FileName should contain the folder and a dummy filename
}

编辑3: 最后看起来,在实际对话中的问题,Visual Studio2005年(我没有访问它早)。 这不是标准的文件开放的对话! 如果你检查窗户的间谍++并比较它们的标准文件,打开,你会看到结构和级的名字不匹配。当你仔细看,你还可以发现一些差异的内容之间的对话。我的结论是,Microsoft完全替换的标准的对话中Visual Studio给它的这种能力。我的解决方案或类似的东西将尽可能靠近你可以得到的,除非你愿意代码你自己从头开始。

好吧,让我尝试连接的第一点;-) 玩一点小小间谍++或Winspector显示,文件夹中的文本框在VS项目的位置是一个自定义的标准的对话。这不是相同的领域作为文件文本在标准文件,对话如在记事本。

从那里,我图,与隐藏的文件和文件类型的文本框/组合框并使用一个定义对话的模板,以增加其自己的部分的底部的对话。

编辑:这是一例这样定义和如何做到这一点(在Win32.不。净):

m_ofn的OPENFILENAME结构的基础文件的对话。添加这些2行:

  m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
  m_ofn.Flags |= OFN_ENABLETEMPLATE;

在IDD_FILEDIALOG_IMPORTXLIFF是一个自定义对话的模板,这将增加在底部的对话。看看这部分红色如下。alt text
(资料来源: apptranslator.com)

在这种情况下,定制的部分仅是一个标签,一个超级链接,但它可能是任何对话。它可以包含一个"确定"的按钮,让我们验证文件夹的唯一选择。

但我们如何摆脱一些控制的标准的一部分的对话,我不知道。

更详细 这MSDN文章.

你可以类的文件对话并获得其所有控制。每个人都有一个标识符,可以用来获得它的窗口处理。然后你可以显示和隐藏他们得到的消息,从他们关于选择的更改等等。等等。这一切取决于如何很大的努力要取。

我们没有我们使用维拓级的支持和定制的文件对话,以包括一个自定义的场所条件在COM景。

MSDN 提供的信息关于如何做到这一使用Win32, 这个演示文包括一个例子, , 这个演示文提供。净例.

你可以用这样的代码

  • 滤波器隐藏的文件
  • 该文件被隐瞒的第一个文本

以先进的隐藏的文本为文件你需要看看 OpenFileDialogEx

代码:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

我假设你在Vista使用VS2008?在这种情况下,我认为 FOS_PICKFOLDERS的选择 正在使用时调用Vista对话文件 IFileDialog.我害怕。净的代码这将涉及大量的粗糙的P/调用互操作码,以获得工作。

第一个解决方案

我发明了这个作为清理的版本 .净赢得7式文件夹选择对话 由比尔登的 lyquidity.com (我没有从属关系).(我知道他的代码 另一个答案在这个页面).我写了我自己,因为他的解决方案需要的额外反射类,不需要对这一重点的目的,使用基于异常的流动的控制,不缓的结果,其反思的电话。注意嵌套静 VistaDialog 类是这样,其静态反射的变量不要尝试去填充如果 Show 方法是从来没有所谓。它回落到预Vista对话,如果未在足够高的窗版本。应该在Windows7、8、9、10和更高(从理论上).

using System;
using System.Reflection;
using System.Windows.Forms;

namespace ErikE.Shuriken {
    /// <summary>
    /// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
    /// </summary>
    public class FolderSelectDialog {
        private string _initialDirectory;
        private string _title;
        private string _fileName = "";

        public string InitialDirectory {
            get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
            set { _initialDirectory = value; }
        }
        public string Title {
            get { return _title ?? "Select a folder"; }
            set { _title = value; }
        }
        public string FileName { get { return _fileName; } }

        public bool Show() { return Show(IntPtr.Zero); }

        /// <param name="hWndOwner">Handle of the control or window to be the parent of the file dialog</param>
        /// <returns>true if the user clicks OK</returns>
        public bool Show(IntPtr hWndOwner) {
            var result = Environment.OSVersion.Version.Major >= 6
                ? VistaDialog.Show(hWndOwner, InitialDirectory, Title)
                : ShowXpDialog(hWndOwner, InitialDirectory, Title);
            _fileName = result.FileName;
            return result.Result;
        }

        private struct ShowDialogResult {
            public bool Result { get; set; }
            public string FileName { get; set; }
        }

        private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title) {
            var folderBrowserDialog = new FolderBrowserDialog {
                Description = title,
                SelectedPath = initialDirectory,
                ShowNewFolderButton = false
            };
            var dialogResult = new ShowDialogResult();
            if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
                dialogResult.Result = true;
                dialogResult.FileName = folderBrowserDialog.SelectedPath;
            }
            return dialogResult;
        }

        private static class VistaDialog {
            private const string c_foldersFilter = "Folders|\n";

            private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
            private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
            private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
            private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
            private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
            private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
            private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialogNative+FOS")
                .GetField("FOS_PICKFOLDERS")
                .GetValue(null);
            private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
                .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
            private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
            private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
            private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");

            public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title) {
                var openFileDialog = new OpenFileDialog {
                    AddExtension = false,
                    CheckFileExists = false,
                    DereferenceLinks = true,
                    Filter = c_foldersFilter,
                    InitialDirectory = initialDirectory,
                    Multiselect = false,
                    Title = title
                };

                var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
                s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
                s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
                var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
                s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);

                try {
                    int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
                    return new ShowDialogResult {
                        Result = retVal == 0,
                        FileName = openFileDialog.FileName
                    };
                }
                finally {
                    s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
                }
            }
        }

        // Wrap an IWin32Window around an IntPtr
        private class WindowWrapper : IWin32Window {
            private readonly IntPtr _handle;
            public WindowWrapper(IntPtr handle) { _handle = handle; }
            public IntPtr Handle { get { return _handle; } }
        }
    }
}

它是用于像这样在一个窗户的形式:

var dialog = new FolderSelectDialog {
    InitialDirectory = musicFolderTextBox.Text,
    Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
    musicFolderTextBox.Text = dialog.FileName;
}

你当然可以玩弄其选择以及什么样的属性,它暴露了.例如,它可以允许多选在Vista式对话。

第二方案

西蒙风穆里耶给了答案 这显示了,如何做到确切的同样的工作,使用互操作对Windows API直接的,虽然他的版本将具有予以补充,使用老式的对话,如果在一个旧版本的Windows。不幸的是,我没有找到他的岗位然而,当我工作了我的解决方案。名字你的毒药!

试试这个 演示 (信贷Nitron):

我认为这是同样的话你说的是-也许它会帮助如果你加入一个截图?

bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
    bool retVal = false;

    // The BROWSEINFO struct tells the shell how it should display the dialog.
    BROWSEINFO bi;
    memset(&bi, 0, sizeof(bi));

    bi.ulFlags   = BIF_USENEWUI;
    bi.hwndOwner = hOwner;
    bi.lpszTitle = szCaption;

    // must call this if using BIF_USENEWUI
    ::OleInitialize(NULL);

    // Show the dialog and get the itemIDList for the selected folder.
    LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

    if(pIDL != NULL)
    {
        // Create a buffer to store the path, then get the path.
        char buffer[_MAX_PATH] = {'\0'};
        if(::SHGetPathFromIDList(pIDL, buffer) != 0)
        {
            // Set the string value.
            folderpath = buffer;
            retVal = true;
        }       

        // free the item id list
        CoTaskMemFree(pIDL);
    }

    ::OleUninitialize();

    return retVal;
}

在Vista可以使用 IFileDialog 与FOS_PICKFOLDERS选项的设定。这将导致显示的OpenFileDialog-等窗口,在这里你可以选择文件夹:

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

老年Windows你总是可以诉诸的伎俩选择的任何文件,在文件夹。

工作实例,工作。净框架2.0和以后可以发现 在这里,.

你可以用这样的代码

滤波器是空的串。文件名是AnyName但不是空白的

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

Ookii对话WPF 图书馆拥有一个类,提供了实现一个文件夹,浏览器对话WPF.

https://github.com/caioproiete/ookii-dialogs-wpf

enter image description here

还有一个版本作用 Windows形式.

我知道问题是在结构 OpenFileDialog 但看到那谷歌把我带到这里我可以指出,如果只是在寻找的文件夹你应该用一个 FolderBrowserDialog 而作为回答此问题的下面

如何指定路径,使用开放式的文件在对话vb.net?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top