选择文件夹对话框WPF

Mik*_* B. 63 .net c# wpf folderbrowserdialog

我开发了一个WPF4应用程序,在我的应用程序中,我需要让用户选择一个应用程序将存储内容的文件夹(文件,生成的报告等).

我的要求:

  • 能够查看标准文件夹树

  • 能够选择文件夹

  • WPF的外观和感觉,此对话框必须看起来像是为Windows Vista/7而不是Windows 2000甚至Win9x设计的现代应用程序的一部分.

据我所知,到2010年(.Net 4.0)将没有标准的文件夹对话框,但是版本4.0可能有一些变化?

或者剩下要做的就是使用老式的WinForms对话框?如果这是我需要的唯一方法,我怎样才能让它更接近Vista/7风格而不是Win9x呢?

在某些论坛上,我看到了这种对话框的实现,但是在Windows 95中看到了丑陋的旧图标.它看起来并不好看.

T P*_*ers 103

Pavel Yosifovich的Windows Presentation Foundation 4.5 Cookbook在第155页的"使用常用对话框"部分中说:

"文件夹选择(而不是文件)怎么样?WPF OpenFileDialog不支持.一种解决方案是使用Windows Forms的FolderBrowseDialog类.另一个很好的解决方案是使用很快描述的Windows API代码包."

我从Windows®APICode PackforMicrosoft®.NETFramework Windows API Code Pack 下载了API Code Pack:它在哪里?,然后将对Microsoft.WindowsAPICodePack.dll和Microsoft.WindowsAPICodePack.Shell.dll的引用添加到我的WPF 4.5项目中.

例:

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
}
Run Code Online (Sandbox Code Playgroud)

  • 我不敢相信微软在WPF中默认不包含FolderBrowserDialog ...... (116认同)
  • Windows API代码包可以通过Nuget [here](http://www.nuget.org/packages/Windows7APICodePack-Shell/)和[here](https://www.nuget.org/packages/Windows7APICodePack-Core)获得/).这对我很有用. (22认同)
  • 它适用于我.另外我只是编写下面的命令,所以帖子包含所有信息.在VS"Install-Package Windows7APICodePack-Core","Install-Package Windows7APICodePack-Shell"中通过Package Manager控制台安装 (3认同)

Nir*_*Nir 21

我很久以前在博客上写过这篇文章,WPF对常见文件对话框的支持非常糟糕(或者至少在3.5版本中没有检查版本4) - 但它很容易解决.

你需要为你的应用程序添加正确的清单 - 这将为你提供一个现代风格的消息框和文件夹浏览器(WinForms FolderBrowserDialog)而不是WPF文件打开/保存对话框,这在3篇帖子中有描述(如果你不在乎关于解释,只希望解决方案直接进入第3):

幸运的是,打开/保存对话框是围绕Win32 API的非常薄的包装器,使用正确的标志可以轻松调用以获得Vista/7样式(在设置清单之后)


zey*_*neh 10

添加在Windows API代码包壳牌到项目

using Microsoft.WindowsAPICodePack.Dialogs;

...

var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
Run Code Online (Sandbox Code Playgroud)


Ste*_*nds 10

FolderBrowserDialogfromSystem.Windows.Forms是显示允许用户选择文件夹的对话框的推荐方法。

直到最近,该对话框的外观和行为与其他文件系统对话框不一致,这也是人们不愿意使用它的原因之一。

好消息是,它FolderBrowserDialog 在 NET Core 3.0 中进行了“现代化”,因此现在对于那些编写针对该版本或更高版本的 Windows 窗体或 WPF 应用程序的人来说是一个可行的选择。

在 .NET Core 3.0 中,Windows 窗体用户[原文如此] Windows Vista 中引入的基于 COM 的较新控件: NET Core 3.0 中的FolderBrowserDialog

在 NET Core WPF 应用程序中引用System.Windows.Forms,需要编辑项目文件并添加以下行:

<UseWindowsForms>true</UseWindowsForms>
Run Code Online (Sandbox Code Playgroud)

它可以直接放置在现有<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)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

FolderBrowserDialog有一个RootFolder属性,据称“设置浏览开始的根文件夹”,但无论我将其设置为什么,都没有任何区别;SelectedPath似乎是用于此目的的更好的属性,但是需要尾随反斜杠。

此外,该ShowNewFolderButton属性似乎也被忽略,无论如何,该按钮总是显示。


小智 8

如果您不想使用Windows窗体或编辑清单文件,我想出了一个非常简单的技巧,即使用WPF的SaveAs对话框来实际选择目录。

无需使用指令,您只需将以下代码复制粘贴即可!

它仍然应该非常用户友好,并且大多数人不会注意到。

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

当然,这是一个大技巧,但也许它将对您的使用效果很好...

在此示例中,我有一个文本框对象来包含结果路径,但是您可以删除相关的行,并根据需要使用返回值...

// 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;
}
Run Code Online (Sandbox Code Playgroud)

此骇客的唯一问题是:

  • 确认按钮仍然显示“保存”,而不是“选择目录”之类的内容,但是在我的情况下,我“保存”目录选择,因此它仍然有效...
  • 输入字段仍然显示“文件名”而不是“目录名”,但是我们可以说目录是一种文件类型...
  • 仍然有一个“另存为类型”下拉列表,但其值显示为“目录(* .this.directory)”,并且用户无法将其更改为其他内容,对我有用。

大多数人不会注意到这些,尽管如果微软想让头脑冷静的话,我绝对会喜欢使用官方的WPF方法,但是直到他们这样做之前,这就是我的临时解决方案。


Han*_*ant 5

Microsoft.Win32.OpenFileDialog是Windows上任何应用程序使用的标准对话框.在.NET 4.0中使用WPF时,您的用户不会对其外观感到惊讶

该对话框在Vista中被更改..NET 3.0和3.5中的WPF仍然使用旧版对话框,但在.NET 4.0中已修复.我只能猜到你开始这个帖子,因为你看到了那个旧对话.这可能意味着您实际上正在运行一个针对3.5的程序.是的,Winforms包装器确实获得了升级并显示了Vista版本.在System.Windows.Forms.OpenFileDialog类中,您需要添加对System.Windows.Forms的引用.

  • 我认为关键是OpenFileDialog不能用于选择文件夹. (16认同)

Oyu*_*yun 5

MVVM + WinForms FolderBrowserDialog作为行为

public class FolderDialogBehavior : Behavior<Button>
{
    public string SetterName { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Click += OnClick;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Click -= OnClick;
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        var dialog = new FolderBrowserDialog();
        var result = dialog.ShowDialog();
        if (result == DialogResult.OK && AssociatedObject.DataContext != null)
        {
            var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(p => p.CanRead && p.CanWrite)
            .Where(p => p.Name.Equals(SetterName))
            .First();

            propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

     <Button Grid.Column="3" Content="...">
            <Interactivity:Interaction.Behaviors>
                <Behavior:FolderDialogBehavior SetterName="SomeFolderPathPropertyName"/>
            </Interactivity:Interaction.Behaviors>
     </Button>
Run Code Online (Sandbox Code Playgroud)

Blogpost:http://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html