我希望用户选择一个目录,我将生成的文件将保存在其中。我知道在WPF中,我应该使用Win32中的OpenFileDialog,但不幸的是,对话框需要选择文件-如果我只是单击确定而不选择一个,它就会保持打开。我可以通过让用户选择一个文件,然后剥离路径以找出它属于哪个目录来“hack”该功能,但这充其量是不直观的。有人见过这种情况吗?
当前回答
正如前面的回答中所述,FolderBrowserDialog是为此使用的类。有些人(有理由)担心这个对话框的外观和行为。好消息是它在NET Core 3.0中被“现代化”了,所以现在对于那些针对该版本或更高版本编写Windows窗体或WPF应用程序的人来说是一个可行的选择(如果你仍然使用NET Framework,那就不走运了)。
在。net Core 3.0中,Windows窗体用户[原文如此]在Windows Vista中引入了一个新的基于com的控件:
要在NET Core WPF应用程序中引用System.Windows.Forms,必须编辑项目文件并添加以下行:
<UseWindowsForms>true</UseWindowsForms>
它可以直接放在现有的<UseWPF>元素之后。
然后就是使用对话框的例子:
using System;
using System.Windows.Forms;
...
using var dialog = new FolderBrowserDialog
{
Description = "Time to select a folder",
UseDescriptionForTitle = true,
SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+ Path.DirectorySeparatorChar,
ShowNewFolderButton = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
...
}
FolderBrowserDialog有一个RootFolder属性,据说“设置浏览开始的根文件夹”,但无论我设置这个没有任何区别;SelectedPath似乎是更好的属性,但是后面的反斜杠是必需的。
此外,ShowNewFolderButton属性似乎也被忽略了,按钮总是显示不管。
其他回答
正如前面的回答中所述,FolderBrowserDialog是为此使用的类。有些人(有理由)担心这个对话框的外观和行为。好消息是它在NET Core 3.0中被“现代化”了,所以现在对于那些针对该版本或更高版本编写Windows窗体或WPF应用程序的人来说是一个可行的选择(如果你仍然使用NET Framework,那就不走运了)。
在。net Core 3.0中,Windows窗体用户[原文如此]在Windows Vista中引入了一个新的基于com的控件:
要在NET Core WPF应用程序中引用System.Windows.Forms,必须编辑项目文件并添加以下行:
<UseWindowsForms>true</UseWindowsForms>
它可以直接放在现有的<UseWPF>元素之后。
然后就是使用对话框的例子:
using System;
using System.Windows.Forms;
...
using var dialog = new FolderBrowserDialog
{
Description = "Time to select a folder",
UseDescriptionForTitle = true,
SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
+ Path.DirectorySeparatorChar,
ShowNewFolderButton = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
...
}
FolderBrowserDialog有一个RootFolder属性,据说“设置浏览开始的根文件夹”,但无论我设置这个没有任何区别;SelectedPath似乎是更好的属性,但是后面的反斜杠是必需的。
此外,ShowNewFolderButton属性似乎也被忽略了,按钮总是显示不管。
Ookii VistaFolderBrowserDialog就是你想要的。
如果你只想要Ooki对话框中的文件夹浏览器,然后下载源代码,为文件夹浏览器挑选你需要的文件(提示:7个文件),它可以在。net 4.5.2中构建。我必须给System.Drawing添加一个引用。将原项目中的参考资料与你的进行比较。
如何确定哪些文件?在不同的Visual Studio实例中打开你的应用程序和Ookii。将VistaFolderBrowserDialog.cs添加到应用程序中,并继续添加文件,直到构建错误消失。你在Ookii项目中找到依赖项-控制-单击你想要跟踪到它的源(双关语)。
如果你懒得这么做,这里有你需要的文件……
NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
COMGuids.cs
ErrorHelper.cs
ShellComInterfaces.cs
ShellWrapperDefinitions.cs
编辑VistaFolderBrowserDialog.cs中的第197行,除非你想包含它们的资源。Resx
抛出新的InvalidOperationException(Properties.Resources.FolderBrowserDialogNoRootFolder);
throw new InvalidOperationException("Unable to retrieve the root folder.");
根据他们的license.txt将他们的版权声明添加到你的应用中
在\Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs第160-169行代码是一个例子,你可以使用,但你需要删除这个,从MessageBox。显示(这个,用于WPF。
在我的机器上工作
对于目录对话框获取目录路径,首先添加引用System.Windows。表单,然后解析,然后把这个代码放在按钮点击。
var dialog = new FolderBrowserDialog();
dialog.ShowDialog();
folderpathTB.Text = dialog.SelectedPath;
(folderpathTB是文本框的名字,我想把文件夹路径,或者你可以把它分配给一个字符串变量也就是)
string folder = dialog.SelectedPath;
如果你想获得文件名/路径,只需在按钮单击上这样做
FileDialog fileDialog = new OpenFileDialog();
fileDialog.ShowDialog();
folderpathTB.Text = fileDialog.FileName;
(folderpathTB是文本框的名字,我想把文件路径,或者你可以把它分配给一个字符串变量太)
注意:对于文件夹对话框,必须将System.Windows.Forms.dll添加到项目中,否则它将无法工作。
对于那些不想创建自定义对话框,但仍然喜欢100% WPF方式,不想使用单独的ddl,额外的依赖项或过时的api的人,我提出了一个非常简单的hack,使用另存为对话框。
不需要使用指令,你可以简单地复制粘贴下面的代码!
它应该仍然是非常友好的,大多数人都不会注意到。
这个想法来自于这样一个事实,我们可以改变对话框的标题,隐藏文件,并很容易地处理产生的文件名。
这是一个大黑客肯定,但也许它会做的工作只是为了你的使用…
在这个例子中,我有一个文本框对象来包含结果路径,但是如果你愿意,你可以删除相关的行,并使用一个返回值…
// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
string path = dialog.FileName;
// Remove fake filename from resulting path
path = path.Replace("\\select.this.directory", "");
path = path.Replace(".this.directory", "");
// If user has changed the filename, create the new directory
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Our final value is in path
textbox.Text = path;
}
这个黑客唯一的问题是:
确认按钮仍然显示“保存”而不是“选择目录”,但在像我这样的情况下,我“保存”目录选择,所以它仍然有效…… 输入字段仍然显示“文件名”而不是“目录名”,但我们可以说目录是一种文件类型… 仍然有一个“另存为类型”下拉菜单,但它的值是“目录(*.this.directory)”,用户不能更改它为其他东西,对我来说…
大多数人不会注意到这些,尽管我肯定更喜欢使用官方的WPF方式,如果微软能把他们的头从他们的屁股里拿出来,但在他们这样做之前,这是我的临时修复。
我建议,在黄金套餐中加入:
Install-Package OpenDialog
那么使用它的方法是:
Gat.Controls.OpenDialogView openDialog = new Gat.Controls.OpenDialogView();
Gat.Controls.OpenDialogViewModel vm = (Gat.Controls.OpenDialogViewModel)openDialog.DataContext;
vm.IsDirectoryChooser = true;
vm.Show();
WPFLabel.Text = vm.SelectedFilePath.ToString();
以下是文档: http://opendialog.codeplex.com/documentation
适用于文件,文件过滤器,文件夹等
推荐文章
- 在窗口上设置设计时间DataContext是一个编译器错误?
- 调用线程必须是STA,因为许多UI组件都要求这一点
- ContentControl和ContentPresenter有什么区别?
- WPF中控制模板和数据模板的区别
- 如何隐藏关闭按钮在WPF窗口?
- UI线程上的任务继续
- WPF数据绑定:我如何访问“父”数据上下文?
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 我应该使用什么MVVM框架?
- 在WPF中引入一个窗口到前面
- 窗口高度=“自动”未按预期工作
- 我如何得到一个动画gif在WPF工作?
- 如何在对话框中创建编辑文本框
- ListBox和ListView的区别是什么
- MVVM:从开始到结束的教程?