【WPF】フォルダ選択ダイアログは一択です【Windows】

C#

こんにちは、働くC#プログラマーのさんさめです。

複数のファイルを一括で出力したいときなど、
ユーザーにフォルダを選択して欲しいことはままあります。

WPFで、フォルダ選択ダイアログを使おうとすると、
いくつか選択肢がありますが、
使いやすさを考えると、事実上一択です

ずばり、
WindowsAPICodePack-Shellをnuget参照して、
CommonOpenFileDialogクラスを使うのがベストです。

というわけで本記事では、
WPFで採用できるフォルダ選択ダイアログの種類と、
その特徴、および、
なぜCommonOpenFileDialogを
使うべきかについて解説します。

スポンサーリンク

フォルダ選択ダイアログの種類

WPFでWindows組み込みのフォルダ選択ダイアログを出すには、
大きく分けて3つの方法があります。

  • FolderBrowserDialog
  • OpenFileDialog
  • CommonOpenFileDialog

それぞれ詳しく見ていきます。

FolderBrowserDialog

WPFでもっとも簡単にフォルダ選択ダイアログを使うならば、
System.Windows.Forms名前空間にある、
FolderBrowserDialogがあります。
これは、参照を追加する必要があります。

といっても、VisualStudioならば、
おもむろにFolderBrowserDialogと入力して
「Ctrl+.」を押せば自動で参照の追加とusingを行ってくれますね。

使い方のサンプルは以下のコードを見てください。

using (var fbd = new FolderBrowserDialog()
{
    Description = "フォルダを選択してください",
    SelectedPath = @"D:\Users\threeshark",
})
{
    // OKが押されずに終わった場合はキャンセルされている
    if (fbd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
    {
        return;
    }

    // SelectedPathで選択されたフォルダを取得する
    System.Windows.MessageBox.Show($"{fbd.SelectedPath}を選択しました");
}

実行すると、
次のような見た目のダイアログが出ます。

どうでしょう。そんなに悪い感じもしませんね。

ところが、何度もフォルダ選択が必要なアプリケーションでは、
このダイアログの使い勝手の悪さが目立ってきます。

具体的には

  • ツリーの展開状況が記憶されないので、
    毎回展開していく必要がある
  • パスを入力する欄が無くジャンプできない
  • 「クイックアクセス」が表示されない

といったことが挙げられます。

OpenFileDialog

次は、ファイル選択ダイアログでおなじみ、
OpenFileDialogです。

名前空間がSystem.Windows.Formsのものと、
Microsoft.Win32のものがありますが、
使い勝手はほぼ同じものとなっております。

使い方は以下のサンプルコードの通り…
なんですが、実はOpenFileDialogには致命的な問題があります。

var ofd = new Microsoft.Win32.OpenFileDialog()
{
    Title = "フォルダを選択してください",
    InitialDirectory = @"D:\Users\threeshark",
    Filter = "Folder|.",
    CheckFileExists = false,
};

// OKが押されずに終わった場合はfalseかnullが返る
if (ofd.ShowDialog() != true)
{
    return;
}

// FileNameで選択されたフォルダを取得したい…のだが、
// そもそもフォルダを選んでOKを押しても
// その中に移動するだけで確定されない
System.Windows.MessageBox.Show($"{ofd.FileName}を選択しました");

そう、OpenFileDialogでは、そもそも
既存フォルダを選択して確定することができないのです。

実行して実際に選択しようとしてOKを押すと、
なんとそのフォルダの中に入ってしまいます。

というわけで、
大きく分けて3つの方法があると言っておいて、
実はこの方法は使えないんですね。
ただ、ファイルを選択する分には、
OpenFileDialogは普通に使えます。

CommonOpenFileDialog

さて、満を持して紹介するのが、
CommonOpenFileDialogです。
これは、nugetからWindowsAPICodePack-Shellを
インストールして参照に追加する必要があります。

似た名前のものがいくつかありますが、
どれを使っても大体同じ使い勝手のクラスが入っています。

こちらは、ちゃんとフォルダを選択する専用のモードがあります。

使い方は以下のコードのようになります。

using (var cofd = new CommonOpenFileDialog()
{
    Title = "フォルダを選択してください",
    InitialDirectory = @"D:\Users\threeshark",
    // フォルダ選択モードにする
    IsFolderPicker = true,
})
{
    if (cofd.ShowDialog() != CommonFileDialogResult.Ok)
    {
        return;
    }

    // FileNameで選択されたフォルダを取得する
    System.Windows.MessageBox.Show($"{cofd.FileName}を選択しました");
}

IsFolderPickerプロパティをtrueにすることで、
フォルダ選択モードにできます。

実行結果は以下のようになります。

先ほどのOpenFileDialogでは、「開く」
だったボタンが「フォルダーの選択」になっていますね。

CommonOpenFileDialogでは、
先ほどFolderBrowserDialogで挙げた、

  • パスを入力する欄が無くジャンプできない
  • 「クイックアクセス」が表示されない

といったデメリットがありません。
いわゆるエクスプローラーとほぼ同じ操作感覚で、
任意のフォルダを選んでもらうことができます。

また、InitialDirectoryを指定せずに、
RestoreDirectoryプロパティをtrueにしておくことで、
次回呼出し時に、
ユーザーが最後に選択したフォルダから始めることができます。

var cofd = new CommonOpenFileDialog()
    {
        Title = "フォルダを選択してください",
        // 最後に選択したフォルダから始まる
        RestoreDirectory = true,
        IsFolderPicker = true,
    }

まとめ

まとめです。

  • WPFでフォルダ選択ダイアログを出すには
    2つの選択肢がある
  • FolderBrowserDialogはややお手軽だが
    使い勝手に難あり
  • CommonOpenFileDialogを
    使った方が便利で気が利いている

最後までお読みいただき、ありがとうございました。

コメント

  1. より:

    質問です。
    このパッケージをインストールして利用しました。
    メニュー(menustrip)から呼び出したのですが、
    クリックして選択フォルダが開いた途端、
    元のウインドウがフォント、ウインドウ共に小さくなってしまいました。
    何か解決方法をご存知でしょうか。

タイトルとURLをコピーしました