WPF 选择文件夹/目录

更新日期: 2022-10-17 阅读次数: 5058 字数: 640 分类: Windows

需求

我需要在 WPF 程序界面上点击按钮,弹出一个选择对话框,选一个目录/文件夹, 然后界面上显示出来这个具体的目录的全路径,同时列出里面所有的文件清单。

(最终使用) System.Windows.Forms.FolderBrowserDialog

我没太看明白为何 github 相关 issue 评论里抗拒使用 WinForm 的方式。

按照:

https://stackoverflow.com/questions/1922204/open-directory-dialog

里所说,WinForm 的 FolderBrowserDialog 在 .Net Core 3.0 之后进行了界面上的升级,看起来更具现代感。 至少我在 Windows 11 上测试,UI 挺好的,跟其他 Windows 11 上的应用看不出有啥不同。

使用 System.Windows.Forms.FolderBrowserDialog 的前提是,在项目 .csproj 配置里增加一行

<UseWindowsForms>true</UseWindowsForms>

修改后的 xxx.csproj 配置文件如下:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWPF>true</UseWPF>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

</Project>

在 Terminal 里开发的好处是,很容易找到这个配置文件,而在 VS 里,还是需要摸索的成本。

具体接口使用,参考官方文档

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.folderbrowserdialog?view=windowsdesktop-6.0

实现代码:

namespace I18nTool
{
    public partial class MainWindow : Window
    {
        private string? folderName;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            using var dialog = new FolderBrowserDialog
            {
                Description = "Select a folder",
                UseDescriptionForTitle = true,
                ShowNewFolderButton = true
            };

            var result = dialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                folderName = dialog.SelectedPath;
                System.Windows.MessageBox.Show(folderName, "Debug");
            }
        }
    }
}

这语法跟 Kotlin 太像了。。。

(未采用) Ookii.Dialogs.Wpf

https://github.com/ookii-dialogs/ookii-dialogs-wpf

从功能介绍来看,Ookii.Dialogs.Wpf 功能强大,且方便使用。但是既然能用内置的功能实现,就暂时不去引入三方依赖了。 估计以后其他场景会用到。

(未采用) FileOpenDialog

Agree I am missing this often too. It is not even that difficult, since you just need to set PICKFOLDERS option on the already existing FileOpenDialog. There is FileDialog.SetOption method to manipulate the options, however, that is internal. Unfortunately it cannot be set by reflection either, since the options are filtered out when creating the dialog, not sure why.Moreover, Visual Studio itself is using that dialog for File | Open | Folder...

但是,我并没有找到官方的示例代码。

为何这么麻烦

我开始不太理解为何这么基础而简单的一个功能,wpf 都不支持。

从 github 相关 issue 里的讨论看,这样一个基础功能,wpf 都不加,在于巨大的历史兼容性负担。

但是微软的根基也在于此,强悍的兼容性,连 xp,Vista 都在兼容。

wpf 与 winform 混用

每个窗口类使用其中一种技术,就可以在一个程序中同时使用 wpf 与 winform。

参考

  • https://github.com/dotnet/wpf/issues/438
  • https://stackoverflow.com/questions/1922204/open-directory-dialog

tags: wpf

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式