以前、こちらの記事でフォルダ選択ダイアログを使ったユーザーコントロールの自作について紹介しました。
今回は、WindowsApiCodePackというライブラリをインストールすることで利用可能な、より洗練されたデザインの「フォルダ選択ダイアログ」について、ライブラリのインストール方法と使い方について紹介したいと思います。
尚、今回はWPFでの使用例を紹介していますが、ライブラリの使い方はWindowsFormと共通であり、またまたFramework も Microsoft Framework 4.7 や 4.8だけでなく、.NET6 でも利用可能です。
フォルダ選択ダイアログの概要
今回紹介するフォルダ選択ダイアログは、以下の様なデザインになります。
前回の記事で紹介したものは、Visual Studioをインストールした際に標準添付されるライブラリを使っていましたので手軽ではありますが、デザインが少し見劣りします。
今回はNugetからWindowsApiCodePackをインストールする必要はありますが、Windows標準のフォルダ選択ダイアログっぽいものが表示されます。

WindowsApiCodePackのインストール方法
インストール方法は、Visual Studioの Nuget でライブラリを選択し、インストールするだけです。
ややこしいのは、どのライブラリを選ぶかです。
Nugetの検索欄で、”WindowsAPICodePack”と入力すると、候補の一覧が表示されます。
似たような名前のライブラリがたくさん表示されますが、「Microsoft-WindowsAPICodePack-Shell」を選んで下さい。
WindowsAPICodePack-ShellとMicrosoft-WindowsAPICodePack-Shell は作者が同一人物ではありますが、微妙に仕様の差異がありますので、間違って選ばないようにご注意ください。

インストールを開始すると、以下のダイアログが表示されます。
Microsoft-WindowsAPICodePack-Shell を選ぶと、依存関係のある Microsoft-WindowsAPICodePack-Core が自動で選択されていることが分かります。
ここで「OK」をクリックすると、インストールできます。

フォルダダイアログの使い方
まず、最初に Microsoft.WindowsAPICodePack.Dialogs をソースコードの冒頭に記述します。
using Microsoft.WindowsAPICodePack.Dialogs;
ダイアログを表示する際は、インスタンスの生成た後で、IsFolderPicker に true を設定し、ShowDialogメソッドを呼びます。
IsFolderPicker が false の場合は、フォルダではなくファイル選択ダイアログとして動作しますので、必ず true を設定して下さい。
var dlg = new CommonOpenFileDialog(); dlg.IsFolderPicker = true; dlg.ShowDialog()
ShowDialogメソッドの戻り値が CommonFileDialogResult.Ok だった場合、FileNameプロパティを使って選択されたフォルダ名を取得します。
if(dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
    folder = dlg.FileName;
}
主なプロパティは次の通りです。
| プロパティ | 内容 | 例 | 
|---|---|---|
| Title | ダイアログのタイトルを設定 | dlg.Title = “フォルダ選択” | 
| IsFolderPicker | ダイアログの動作を設定 true:フォルダ選択ダイアログ false:ファイル選択ダイアログ 省略時はfalseが設定されている | dlg.IsFolderPicker = true; | 
| InitialDirectory | ダイアログ表示時の選択候補となるフォルダ 省略すると直近のフォルダが選択される | dlg.InitialDirectory = @”C:\” | 
| DefaultDirectory | 直近に表示したフォルダが見つからない場合の 代替フォルダ | dlg.DefaultDirectory = @”C:\Temp\”; | 
サンプルソース
今回のサンプルプログラムはWPF+C#+.NET6.0 という構成です。
WinApiFileDialogSample という名前でプロジェクトを作成しました。
まずはXAMLのソースコードです。
<Window x:Class="WinApiFileDialogSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WinApiFileDialogSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="358" Width="513">
    <Grid>
        <Button x:Name="uxOpenFolder" Content="OpenFolder" HorizontalAlignment="Center" Margin="0,71,0,0" VerticalAlignment="Top" Height="30" Width="300" Click="uxOpenFolder_Click" />
        <TextBox x:Name="uxResult" HorizontalAlignment="Center" Margin="0,146,0,0" VerticalAlignment="Top" Height="25" Width="300"/>
    </Grid>
</Window>
次に、C#のソースコードです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.WindowsAPICodePack.Dialogs;
namespace WinApiFileDialogSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        /// <summary>
        /// フォルダオープンダイアログ
        /// </summary>
        /// <returns></returns>
        public string OpenFolderDialog()
        {
            //ダイアログのインスタンス生成
            var dlg = new CommonOpenFileDialog();
            //初期設定
            dlg.Title = "フォルダ選択";
            dlg.IsFolderPicker = true;             //フォルダ選択ダイアログの場合はtrue
            dlg.InitialDirectory = @"C:\";             //開いておきたいフォルダ
            dlg.DefaultDirectory = @"C:\Users\TEMP";   //直近に使用したフォルダが利用できない時の代替えフォルダ
            //ダイアログの表示
            var res = dlg.ShowDialog();
            //戻り値がOKならファイル名を、そうでなければ空文字を返す
            return (res == CommonFileDialogResult.Ok) ? dlg.FileName : "";
        }
        /// <summary>
        /// OpenFolder ボタンクリック時のイベントハンドラ
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uxOpenFolder_Click(object sender, RoutedEventArgs e)
        {
            uxResult.Text = OpenFolderDialog();
        }
    }
}
まとめ
今回は、WindowsApiCodePack というフリーのライブラリを使ってフォルダ選択ダイアログを表示するために、Nugetを使ったインストール方法と、ダイアログの表示、選択されたフォルダの取得方法について解説しました。
WindowsApiCodePack をインストールする必要はありますが、見た目は美しいので、見た目にこだわる方は是非このライブラリをご活用ください。
この記事が、皆様のプログラミングの一助になれば幸いです。