.net 你如何配置一个 OpenFileDialog 来选择文件夹?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 09:41:17  来源:igfitidea点击:

How do you configure an OpenFileDialog to select folders?

.netwindowswinapiopenfiledialog

提问by OwenP

In VS .NET, when you are selecting a folder for a project, a dialog that looks like an OpenFileDialog or SaveFileDialog is displayed, but is set up to accept only folders. Ever since I've seen this I've wanted to know how it's done. I am aware of the FolderBrowserDialog, but I've never really liked that dialog. It starts too small and doesn't let me take advantage of being able to type a path.

在 VS .NET 中,当您为项目选择文件夹时,会显示一个类似于 OpenFileDialog 或 SaveFileDialog 的对话框,但设置为仅接受文件夹。自从我看到这个我就想知道它是怎么做的。我知道 FolderBrowserDialog,但我从来没有真正喜欢过那个对话框。它开始时太小,不能让我利用能够输入路径的优势。

I'm almost certain by now there's not a way to do this from .NET, but I'm just as curious how you do it from unmanaged code as well. Short of completely reimplementing the dialog from scratch, how do you modify the dialog to have this behavior?

我现在几乎可以肯定,没有办法从 .NET 中做到这一点,但我同样好奇您如何从非托管代码中做到这一点。没有从头开始完全重新实现对话框,您如何修改对话框以具有这种行为?

I'd also like to restate that I am aware of the FolderBrowserDialog but sometimes I don't like to use it, in addition to being genuinely curious how to configure a dialog in this manner. Telling me to just use the FolderBrowserDialog helps me maintain a consistent UI experience but doesn't satisfy my curiosity so it won't count as an answer.

我还想重申一下,我知道 FolderBrowserDialog 但有时我不喜欢使用它,除了真的很好奇如何以这种方式配置对话框之外。告诉我只使用 FolderBrowserDialog 可以帮助我保持一致的 UI 体验,但不能满足我的好奇心,所以它不能算作答案。

It's not a Vista-specific thing either; I've been seeing this dialog since VS .NET 2003, so it is doable in Win2k and WinXP. This is less of a "I want to know the proper way to do this" question and more of a "I have been curious about this since I first wanted to do it in VS 2003" question. I understand that Vista's file dialog has an option to do this, but it's been working in XP so I know they did somethingto get it to work. Vista-specific answers are not answers, because Vista doesn't exist in the question context.

它也不是特定于 Vista 的东西。我从 VS .NET 2003 开始​​就看到这个对话框,所以它在 Win2k 和 WinXP 中是可行的。这不是“我想知道执行此操作的正确方法”的问题,而是“自从我第一次想在 VS 2003 中执行此操作以来我一直对此感到好奇”的问题。我知道 Vista 的文件对话框有一个选项可以做到这一点,但它一直在 XP 中工作,所以我知道他们做了一些事情来让它工作。特定于 Vista 的答案不是答案,因为问题上下文中不存在 Vista。

Update: I'm accepting Scott Wisniewski's answer because it comes with a working sample, but I think Serge deserves credit for pointing to the dialog customization (which is admittedly nasty from .NET but it doeswork) and Mark Ransom for figuring out that MS probably rolled a custom dialog for this task.

更新:我接受 Scott Wisniewski 的回答,因为它附带了一个工作示例,但我认为 Serge 值得称赞指出对话框自定义(这在 .NET 中确实令人讨厌,但它确实有效)和 Mark Ransom 指出了 MS可能为此任务推出了一个自定义对话框。

采纳答案by Scott Wisniewski

I have a dialog that I wrote called an OpenFileOrFolder dialog that allows you to open either a folder or a file.

我有一个我编写的对话框,称为 OpenFileOrFolder 对话框,它允许您打开文件夹或文件。

If you set its AcceptFiles value to false, then it operates in only accept folder mode.

如果将其 AcceptFiles 值设置为 false,则它仅在接受文件夹模式下运行。

You can download the source from GitHub here

您可以在此处从 GitHub 下载源代码

回答by Cheeso

You can use FolderBrowserDialogEx- a re-usable derivative of the built-in FolderBrowserDialog. This one allows you to type in a path, even a UNC path. You can also browse for computers or printers with it. Works just like the built-in FBD, but ... better.

您可以使用FolderBrowserDialogEx- 内置 FolderBrowserDialog 的可重用派生。这允许您输入路径,甚至是 UNC 路径。您还可以使用它浏览计算机或打印机。就像内置的 FBD 一样工作,但......更好。

(EDIT: I should have pointed out that this dialog can be set to select files or folders. )

(编辑:我应该指出这个对话框可以设置为选择文件或文件夹。)

Full Source code (one short C# module). Free. MS-Public license.

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

Code to use it:

使用它的代码:

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;
}

回答by Ken Wayne VanderLinde

There is the Windows API Code Pack. It's got a lot of shell related stuff, including the CommonOpenFileDialogclass (in the Microsoft.WindowsAPICodePack.Dialogsnamespace). This is the perfect solution - the usual open dialog with only folders displayed.

有 Windows API 代码包。它有很多与 shell 相关的东西,包括CommonOpenFileDialog类(在Microsoft.WindowsAPICodePack.Dialogs命名空间中)。这是完美的解决方案 - 通常只显示文件夹的打开对话框。

Here is an example of how to use it:

以下是如何使用它的示例:

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


Unfortunately Microsoft no longer ships this package, but several people have unofficially uploaded binaries to NuGet. One example can be found here. This package is just the shell-specific stuff. Should you need it, the same user has several other packages which offer more functionality present in the original package.

不幸的是,微软不再提供这个包,但有几个人已经非正式地将二进制文件上传到 NuGet。一个例子可以在这里找到。这个包只是特定于 shell 的东西。如果您需要它,同一个用户还有其他几个包,它们提供了原始包中存在的更多功能。

回答by Christian Klauser

The Ookii.Dialogspackage contains a managed wrapper around the new (Vista-style) folder browser dialog. It also degrades gracefully on older operating systems.

Ookii.Dialogs包中包含的文件夹浏览器对话框,围绕新(Vista风格)托管的包装。它也会在较旧的操作系统上正常降级。

回答by Ryan Farley

Better to use the FolderBrowserDialog for that.

最好为此使用 FolderBrowserDialog。

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

回答by Alex Essilfie

After hours of searching I found this answerby leetNightShadeto a working solution.

经过数小时的搜索,我通过leetNightShade找到了一个有效解决方案的答案

There are three things I believe make this solution much better than all the others.

我相信有三件事使这个解决方案比所有其他解决方案都要好得多。

  1. It is simple to use.It only requires you include two files (which can be combined to one anyway) in your project.
  2. It falls back to the standard FolderBrowserDialogwhen used on XP or older systems.
  3. The author grants permission to use the code for any purpose you deem fit.

    There's no license as such as you are free to take and do with the code what you will.

  1. 使用起来很简单。它只需要您在项目中包含两个文件(无论如何都可以合并为一个)。
  2. 在 XP 或更旧的系统上使用时,它会回退到标准的FolderBrowserDialog
  3. 作者授权将代码用于您认为合适的任何目的。

    没有任何许可证,您可以随意使用代码并随心所欲。

Download the code here.

此处下载代码。

回答by Serge Wautier

OK, let me try to connect the first dot ;-) Playing a little bit with Spy++ or Winspector shows that the Folder textbox in the VS Project Location is a customization of the standard dialog. It's not the same field as the filename textbox in a standard file dialog such as the one in Notepad.

好的,让我尝试连接第一个点 ;-) 用 Spy++ 或 Winspector 稍微玩一下,显示 VS 项目位置中的文件夹文本框是标准对话框的自定义。它与标准文件对话框(例如记事本中的对话框)中的文件名文本框不同。

From there on, I figure, VS hides the filename and filetype textboxes/comboboxes and uses a custom dialog template to add its own part in the bottom of the dialog.

从那时起,我认为 VS 隐藏了文件名和文件类型文本框/组合框,并使用自定义对话框模板在对话框底部添加自己的部分。

EDIT: Here's an example of such customization and how to do it (in Win32. not .NET):

编辑:这是此类自定义的示例以及如何执行此操作(在 Win32 中。而不是 .NET):

m_ofn is the OPENFILENAME struct that underlies the file dialog. Add these 2 lines:

m_ofn 是作为文件对话框基础的 OPENFILENAME 结构。添加以下两行:

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

where IDD_FILEDIALOG_IMPORTXLIFF is a custom dialog template that will be added in the bottom of the dialog. See the part in red below. alt text
(source: apptranslator.com)

其中 IDD_FILEDIALOG_IMPORTXLIFF 是将添加到对话框底部的自定义对话框模板。请参阅下面的红色部分。 (来源:apptranslator.com替代文字

In this case, the customized part is only a label + an hyperlink but it could be any dialog. It could contain an OK button that would let us validate folder only selection.

在这种情况下,自定义部分只是一个标签+一个超链接,但它可以是任何对话框。它可以包含一个确定按钮,让我们仅验证文件夹选择。

But how we would get rid of some of the controls in the standard part of the dialog, I don't know.

但是我们将如何摆脱对话框标准部分中的一些控件,我不知道。

More detail in this MSDN article.

这篇 MSDN 文章中有更多详细信息。

回答by Mark Ransom

Exact Audio Copyworks this way on Windows XP. The standard file open dialog is shown, but the filename field contains the text "Filename will be ignored".

Exact Audio Copy在 Windows XP 上以这种方式工作。显示标准文件打开对话框,但文件名字段包含文本“文件名将被忽略”。

Just guessing here, but I suspect the string is injected into the combo box edit control every time a significant change is made to the dialog. As long as the field isn't blank, and the dialog flags are set to not check the existence of the file, the dialog can be closed normally.

只是在这里猜测,但我怀疑每次对对话框进行重大更改时,都会将字符串注入组合框编辑控件中。只要该字段不为空,并且对话框标志设置为不检查文件是否存在,对话框就可以正常关闭。

Edit:this is much easier than I thought. Here's the code in C++/MFC, you can translate it to the environment of your choice.

编辑:这比我想象的要容易得多。这是 C++/MFC 中的代码,您可以将其转换为您选择的环境。

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

Edit 2:This should be the translation to C#, but I'm not fluent in C# so don't shoot me if it doesn't work.

编辑 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
}

Edit 3:Finally looked at the actual dialog in question, in Visual Studio 2005 (I didn't have access to it earlier). It is not the standard file open dialog!If you inspect the windows in Spy++ and compare them to a standard file open, you'll see that the structure and class names don't match. When you look closely, you can also spot some differences between the contents of the dialogs. My conclusion is that Microsoft completely replaced the standard dialog in Visual Studio to give it this capability. My solution or something similar will be as close as you can get, unless you're willing to code your own from scratch.

编辑 3:最后在 Visual Studio 2005 中查看了有问题的实际对话框(我之前无法访问它)。它不是标准的文件打开对话框!如果您检查 Spy++ 中的窗口并将它们与打开的标准文件进行比较,您会发现结构和类名不匹配。当您仔细观察时,您还可以发现对话框内容之间的一些差异。我的结论是,微软完全取代了 Visual Studio 中的标准对话框来赋予它这种能力。我的解决方案或类似的东西将尽可能接近您,除非您愿意从头开始编写自己的代码。

回答by Jeff Yates

You can subclass the file dialog and gain access to all its controls. Each has an identifier that can be used to obtain its window handle. You can then show and hide them, get messages from them about selection changes etc. etc. It all depends how much effort you want to take.

您可以将文件对话框子类化并访问其所有控件。每个都有一个标识符,可用于获取其窗口句柄。然后,您可以显示和隐藏它们,从他们那里获取有关选择更改等的消息等。这完全取决于您想要付出多少努力。

We did ours using WTL class support and customized the file dialog to include a custom places bar and plug-in COM views.

我们使用 WTL 类支持完成了我们的工作,并自定义了文件对话框以包含自定义位置栏和插件 COM 视图。

MSDNprovides information on how to do this using Win32, this CodeProject article includes an example, and this CodeProject article provides a .NET example.

MSDN提供了有关如何使用 Win32 执行此操作的信息,此 CodeProject 文章包含一个示例此 CodeProject 文章提供了一个 .NET 示例

回答by Avram

You can use code like this

你可以使用这样的代码

  • The filter is hide files
  • The filename is hide first text
  • 过滤器是隐藏文件
  • 文件名是隐藏第一个文本

To advanced hide of textbox for filename you need to look at OpenFileDialogEx

要高级隐藏文件名的文本框,您需要查看 OpenFileDialogEx

The code:

编码:

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