如何配置OpenFileDialog选择文件夹?
在VS .NET中,当我们为项目选择文件夹时,将显示一个对话框,看起来像一个OpenFileDialog或者SaveFileDialog,但设置为仅接受文件夹。自从我看到这一点以来,我一直想知道它是如何完成的。我知道FolderBrowserDialog,但我从未真正喜欢过该对话框。它开始时太小,不能让我利用能够输入路径的优势。
我几乎可以肯定的是,目前尚无从.NET执行此操作的方法,但我也很好奇我们也如何从非托管代码中执行此操作。缺少从头开始完全重新实现对话框的方法,如何修改对话框以具有此行为?
我还想重申一下,我知道FolderBrowserDialog,但有时我不喜欢使用它,除了真正好奇如何以这种方式配置对话框。告诉我只使用FolderBrowserDialog可以帮助我保持一致的UI体验,但不能满足我的好奇心,因此它不会被视为答案。
这也不是Vista特有的。自VS .NET 2003以来,我一直在看到此对话框,因此它在Win2k和WinXP中是可行的。这不是一个"我想知道执行此操作的正确方法"的问题,而更多的是"自从我第一次在VS 2003中开始做以来,我对此一直感到好奇"。我知道Vista的文件对话框可以执行此操作,但是它在XP中一直在运行,因此我知道他们做了一些努力使其能够正常工作。 Vista特定的答案不是答案,因为问题上下文中不存在Vista。
更新:我接受Scott Wisniewski的回答,因为它附带了一个有效的示例,但是我认为Serge值得称赞的是他指出了对话框的自定义功能(虽然从.NET来看这很讨厌,但它确实有效),而Mark Ransom则指出了MS可能为此任务滚动了一个自定义对话框。
解决方案
回答
最好为此使用FolderBrowserDialog。
using (FolderBrowserDialog dlg = new FolderBrowserDialog()) { dlg.Description = "Select a folder"; if (dlg.ShowDialog() == DialogResult.OK) { MessageBox.Show("You selected: " + dlg.SelectedPath); } }
回答
我假设我们在使用VS2008的Vista上?在那种情况下,我认为在调用Vista文件对话框IFileDialog时会使用FOS_PICKFOLDERS选项。恐怕在.NET代码中,这将涉及大量讨厌的P / Invoke互操作代码才能起作用。
回答
好,让我尝试连接第一个点;-)
与Spy ++或者Winspector一起玩一点,表明VS Project Location中的Folder文本框是对标准对话框的自定义。它与标准文件对话框(如记事本中的文件名)中的文件名文本框不同。
从那里开始,我认为VS隐藏了文件名和文件类型文本框/组合框,并使用自定义对话框模板在对话框底部添加了自己的部分。
编辑:这是这种自定义以及如何进行此操作的示例(在Win32. 不是.NET):
m_ofn是文件对话框基础的OPENFILENAME结构。添加以下两行:
m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF); m_ofn.Flags |= OFN_ENABLETEMPLATE;
其中IDD_FILEDIALOG_IMPORTXLIFF是自定义对话框模板,将添加到对话框底部。请参见下面红色部分。
替代文字http://apptranslator.com/_so/customizedfiledialog.png
在这种情况下,自定义部分仅是标签+超链接,但可以是任何对话框。它可能包含一个"确定"按钮,使我们可以验证仅文件夹选择。
但是我不知道该如何摆脱对话框标准部分中的某些控件。
此MSDN文章中有更多详细信息。
回答
尝试从Codeproject(贷给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] = {'CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this); dlg.DoModal();'}; if(::SHGetPathFromIDList(pIDL, buffer) != 0) { // Set the string value. folderpath = buffer; retVal = true; } // free the item id list CoTaskMemFree(pIDL); } ::OleUninitialize(); return retVal; }
回答
我们可以对文件对话框进行子类化,并访问其所有控件。每个都有一个可用于获取其窗口句柄的标识符。然后,我们可以显示和隐藏它们,从中获取有关选择更改等的消息。等等。这一切都取决于我们要付出多少努力。
我们使用WTL类支持来完成我们的工作,并自定义文件对话框以包括自定义位置栏和插件COM视图。
MSDN提供了有关如何使用Win32进行此操作的信息,此CodeProject文章包括一个示例,而此CodeProject文章提供一个.NET示例。
回答
精确音频复制在Windows XP上可以这种方式工作。将显示标准文件打开对话框,但文件名字段包含文本"文件名将被忽略"。
只是在这里猜测,但是我怀疑每次对对话框进行重大更改时,字符串都会注入到组合框编辑控件中。只要该字段不是空白,并且对话框标志设置为不检查文件是否存在,就可以正常关闭对话框。
编辑:这比我想象的要容易得多。这是C ++ / MFC中的代码,我们可以将其转换为我们选择的环境。
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 }
编辑2:这应该是C#的翻译,但是我不太熟练Cso,如果它不起作用,请不要开枪打我。
{ openFileDialog2.FileName = "\r"; openFileDialog1.Filter = "folders|*.neverseenthisfile"; openFileDialog1.CheckFileExists = false; openFileDialog1.CheckPathExists = false; }
编辑3:最后查看了在Visual Studio 2005中存在问题的实际对话框(我之前没有访问权限)。它不是标准文件打开对话框!如果我们在Spy ++中检查窗口并将它们与打开的标准文件进行比较,则会看到结构和类名不匹配。当我们仔细观察时,还可以发现对话框内容之间的一些差异。我的结论是,Microsoft完全替换了Visual Studio中的标准对话框以提供此功能。我的解决方案或者类似的解决方案将尽可能地接近我们,除非我们愿意从头开始编写自己的代码。
回答
Ookii.Dialogs程序包包含新的(Vista风格)文件夹浏览器对话框周围的托管包装。在较旧的操作系统上,它也会正常降级。
回答
我们可以使用这样的代码
- 筛选器是隐藏文件
- 文件名是隐藏第一个文本
要高级隐藏文本框的文件名,我们需要查看
打开文件对话框
代码:
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; }
回答
我编写了一个对话框,称为OpenFileOrFolder对话框,该对话框可让我们打开文件夹或者文件。
如果将其AcceptFiles值设置为false,则它仅在接受文件夹模式下运行。
我们可以在此处从GitHub下载源代码
回答
我们可以使用FolderBrowserDialogEx
内置FolderBrowserDialog的可重用派生类。这使我们可以键入一个路径,甚至是UNC路径。我们也可以使用它浏览计算机或者打印机。就像内置的FBD一样工作,但是……更好。
(编辑:我应该指出,可以将此对话框设置为选择文件或者文件夹。)
完整的源代码(一个简短的Cmodule)。自由。 MS-公共许可证。
使用它的代码:
##代码##