wpf 打开目录对话框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1922204/
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-08 21:20:40  来源:igfitidea点击:

Open directory dialog

wpffilesystemsdialog

提问by Alexandra

I want the user to select a directory where a file that I will then generate will be saved. I know that in WPF I should use the OpenFileDialogfrom Win32, but unfortunately the dialog requires file(s) to be selected - it stays open if I simply click OK without choosing one. I could "hack up" the functionality by letting the user pick a file and then strip the path to figure out which directory it belongs to but that's unintuitive at best. Has anyone seen this done before?

我希望用户选择一个目录,我将生成的文件将保存在该目录中。我知道在 WPF 中我应该使用OpenFileDialog来自 Win32 的,但不幸的是对话框需要选择文件 - 如果我只是单击确定而不选择一个文件,它会保持打开状态。我可以通过让用户选择一个文件然后剥离路径来确定它属于哪个目录来“破解”该功能,但这充其量是不直观的。有没有人见过这样做过?

回答by Heinzi

You can use the built-in FolderBrowserDialogclass for this. Don't mind that it's in the System.Windows.Formsnamespace.

您可以为此使用内置的FolderBrowserDialog类。不要介意它在System.Windows.Forms命名空间中。

using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
    System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}

If you want the window to be modal over some WPF window, see the question How to use a FolderBrowserDialog from a WPF application.

如果您希望窗口在某个 WPF 窗口上是模态的,请参阅问题How to use a FolderBrowserDialog from a WPF application



EDIT:If you want something a bit more fancy than the plain, ugly Windows Forms FolderBrowserDialog, there are some alternatives that allow you to use the Vista dialog instead:

编辑:如果你想要比普通的、丑陋的 Windows 窗体 FolderBrowserDialog 更花哨的东西,有一些替代方法可以让你使用 Vista 对话框:

  • Third-party libraries, such as Ookii dialogs(.NET 3.5)
  • The Windows API Code Pack-Shell:

    using Microsoft.WindowsAPICodePack.Dialogs;
    
    ...
    
    var dialog = new CommonOpenFileDialog();
    dialog.IsFolderPicker = true;
    CommonFileDialogResult result = dialog.ShowDialog();
    

    Note that this dialog is not available on operating systems older than Windows Vista, so be sure to check CommonFileDialog.IsPlatformSupportedfirst.

  • 第三方库,例如Ookii 对话框(.NET 3.5)
  • Windows API的代码包壳牌

    using Microsoft.WindowsAPICodePack.Dialogs;
    
    ...
    
    var dialog = new CommonOpenFileDialog();
    dialog.IsFolderPicker = true;
    CommonFileDialogResult result = dialog.ShowDialog();
    

    请注意,此对话框在早于 Windows Vista 的操作系统上不可用,因此请务必先检查CommonFileDialog.IsPlatformSupported

回答by adrianm

I created a UserControl which is used like this:

我创建了一个像这样使用的 UserControl:

  <UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>

The xaml source looks like this:

xaml 源代码如下所示:

<UserControl x:Class="Utilities.WPF.FolderEntry"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DockPanel>
        <Button Margin="0" Padding="0" DockPanel.Dock="Right" Width="Auto" Click="BrowseFolder">...</Button>
        <TextBox Height="Auto" HorizontalAlignment="Stretch" DockPanel.Dock="Right" 
           Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </DockPanel>
</UserControl>

and the code-behind

和代码隐藏

public partial class FolderEntry {
    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FolderEntry), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(FolderEntry), new PropertyMetadata(null));

    public string Text { get { return GetValue(TextProperty) as string; } set { SetValue(TextProperty, value); }}

    public string Description { get { return GetValue(DescriptionProperty) as string; } set { SetValue(DescriptionProperty, value); } }

    public FolderEntry() { InitializeComponent(); }

    private void BrowseFolder(object sender, RoutedEventArgs e) {
        using (FolderBrowserDialog dlg = new FolderBrowserDialog()) {
            dlg.Description = Description;
            dlg.SelectedPath = Text;
            dlg.ShowNewFolderButton = true;
            DialogResult result = dlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                Text = dlg.SelectedPath;
                BindingExpression be = GetBindingExpression(TextProperty);
                if (be != null)
                    be.UpdateSource();
            }
        }
    }
 }

回答by Rafael

I'm using Ookii dialogsfor a while and it work nice for WPF.

我使用Ookii 对话框有一段时间了,它适用于 WPF。

Here's the direct page:

这是直接页面:

http://www.ookii.org/Blog/new_download_ookiidialogs

http://www.ookii.org/Blog/new_download_ookiidialogs

回答by Youngjae

Ookii folder dialog can be found at Nuget.

可以在 Nuget 找到 Ookii 文件夹对话框。

PM> Install-Package Ookii.Dialogs

PM> Install-Package Ookii.Dialogs

And, example code is as below.

并且,示例代码如下。

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
    textBoxFolderPath.Text = dialog.SelectedPath;
}

回答by Olivier St-L

For those who don't want to create a custom dialog but still prefer a 100% WPF way and don't want to use separate DDLs, additional dependencies or outdated APIs, I came up with a very simple hack using the Save As dialog.

对于那些不想创建自定义对话框但仍然喜欢 100% WPF 方式并且不想使用单独的 DDL、附加依赖项或过时的 API 的人,我想出了一个使用另存为对话框的非常简单的技巧。

No using directive needed, you may simply copy-paste the code below !

不需要 using 指令,您可以简单地复制粘贴下面的代码!

It should still be very user-friendly and most people will never notice.

它应该仍然非常人性化,大多数人永远不会注意到。

The idea comes from the fact that we can change the title of that dialog, hide files, and work around the resulting filename quite easily.

这个想法来自这样一个事实,即我们可以很容易地更改该对话框的标题、隐藏文件并解决生成的文件名。

It is a big hack for sure, but maybe it will do the job just fine for your usage...

这肯定是一个很大的黑客,但也许它可以很好地满足您的使用......

In this example I have a textbox object to contain the resulting path, but you may remove the related lines and use a return value if you wish...

在这个例子中,我有一个文本框对象来包含结果路径,但是如果你愿意,你可以删除相关的行并使用返回值......

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

The only issues with this hack are :

这个黑客的唯一问题是:

  • Acknowledge button still says "Save" instead of something like "Select directory", but in a case like mines I "Save" the directory selection so it still works...
  • Input field still says "File name" instead of "Directory name", but we can say that a directory is a type of file...
  • There is still a "Save as type" dropdown, but its value says "Directory (*.this.directory)", and the user cannot change it for something else, works for me...
  • 确认按钮仍然显示“保存”而不是“选择目录”之类的内容,但在像地雷这样的情况下,我“保存”目录选择,因此它仍然有效......
  • 输入字段仍然显示“文件名”而不是“目录名”,但我们可以说目录是一种文件......
  • 仍然有一个“另存为类型”下拉菜单,但它的值显示为“目录(*.this.directory)”,用户无法将其更改为其他内容,对我有用...

Most people won't notice these, although I would definitely prefer using an official WPF way if microsoft would get their heads out of their asses, but until they do, that's my temporary fix.

大多数人不会注意到这些,尽管我肯定更喜欢使用官方的 WPF 方式,如果微软能把他们的脑袋从他们的屁股中解脱出来,但在他们这样做之前,这是我的临时解决方案。

回答by Zia Ur Rahman

For Directory Dialog to get the Directory Path, First Add reference System.Windows.Forms, and then Resolve, and then put this code in a button click.

对于Directory Dialog 获取目录路径,首先添加引用System.Windows.Forms,然后Resolve,然后把这段代码放在一个按钮上点击。

    var dialog = new FolderBrowserDialog();
    dialog.ShowDialog();
    folderpathTB.Text = dialog.SelectedPath;

(folderpathTB is name of TextBox where I wana put the folder path, OR u can assign it to a string variable too i.e.)

(folderpathTB 是 TextBox 的名称,我想在其中放置文件夹路径,或者您也可以将其分配给字符串变量,即)

    string folder = dialog.SelectedPath;

And if you wana get FileName/path, Simply do this on Button Click

如果您想获得文件名/路径,只需单击按钮即可

    FileDialog fileDialog = new OpenFileDialog();
    fileDialog.ShowDialog();
    folderpathTB.Text = fileDialog.FileName;

(folderpathTB is name of TextBox where I wana put the file path, OR u can assign it to a string variable too)

(folderpathTB 是 TextBox 的名称,我想在其中放置文件路径,或者您也可以将其分配给字符串变量)

Note: For Folder Dialog, the System.Windows.Forms.dll must be added to the project, otherwise it wouldn't work.

注意:对于文件夹对话框,必须在项目中添加 System.Windows.Forms.dll,否则将不起作用。

回答by Saurabh Raoot

I found the below code on below link... and it worked Select folder dialog WPF

我在下面的链接上找到了下面的代码......并且它起作用了 选择文件夹对话框 WPF

using Microsoft.WindowsAPICodePack.Dialogs;

var dlg = new CommonOpenFileDialog();
dlg.Title = "My Title";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = currentDirectory;

dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = currentDirectory;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;

if (dlg.ShowDialog() == CommonFileDialogResult.Ok) 
{
  var folder = dlg.FileName;
  // Do something with selected folder string
}

回答by bigworld12

The best way to achieve what you want is to create your own wpf based control , or use a one that was made by other people
why ? because there will be a noticeable performance impact when using the winforms dialog in a wpf application (for some reason)
i recommend this project
https://opendialog.codeplex.com/
or Nuget :

实现您想要的最佳方法是创建自己的基于 wpf 的控件,或者使用其他人制作的控件,
为什么?因为在 wpf 应用程序中使用 winforms 对话框时会有明显的性能影响(出于某种原因)
我推荐这个项目
https://opendialog.codeplex.com/
或 Nuget :

PM> Install-Package OpenDialog

it's very MVVM friendly and it isn't wraping the winforms dialog

它对 MVVM 非常友好,并且没有包装 winforms 对话框

回答by Jose Ortega

I'd suggest, to add in the nugget package:

我建议,在 nugget 包中添加:

  Install-Package OpenDialog

Then the way to used it is:

那么使用方法是:

    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();

Here's the documentation: http://opendialog.codeplex.com/documentation

这是文档:http: //opendialog.codeplex.com/documentation

Works for Files, files with filter, folders, etc

适用于文件、带过滤器的文件、文件夹等

回答by Gregory Eaton

I know this is an old question, but a simple way to do this is use the FileDialog option provided by WPF and using System.IO.Path.GetDirectory(filename).

我知道这是一个老问题,但一个简单的方法是使用 WPF 提供的 FileDialog 选项并使用 System.IO.Path.GetDirectory(filename)。