C#でフォルダ選択ダイアログを実装する方法|FolderBrowserDialog・OpenFileDialogの違いと使い方

はじめに

C#でアプリケーションを作成していると、ユーザーに保存先や読み込み元のフォルダを選択してもらいたい場面があります。このような場合に使うのが、フォルダ選択ダイアログです。

C#では、主にFolderBrowserDialogを使うことで、Windows標準のフォルダ選択画面を簡単に表示できます。一方で、似た名前のOpenFileDialogは本来ファイル選択用であり、フォルダ選択とは用途が異なります。

この記事では、C#でフォルダ選択ダイアログを実装する基本から、FolderBrowserDialogの使い方、WPFでの利用方法、.NET Framework.NET 5以降での違い、よくあるエラーの対処法まで解説します。

1. C#でフォルダ選択ダイアログを実装する基本

1-1. フォルダ選択ダイアログとは

フォルダ選択ダイアログとは、ユーザーがPC上のフォルダを画面上で選択できるダイアログです。

たとえば、次のような画面を表示して、ユーザーに任意のフォルダを選んでもらいます。

C#
using var dialog = new FolderBrowserDialog();
dialog.ShowDialog();

ユーザーがフォルダを選択すると、そのフォルダのパスをC#側で取得できます。

1-2. C#でフォルダ選択が必要になる主な場面

C#でフォルダ選択が必要になる場面は多くあります。

たとえば、ログファイルの保存先を指定する場合、画像やCSVファイルをまとめて読み込む場合、バックアップ先を選択する場合などです。

ファイル単体ではなく、フォルダ全体を対象に処理したい場合は、フォルダ選択ダイアログを使うのが基本です。

1-3. 使用する主なクラスはFolderBrowserDialog

C#でフォルダ選択を行う代表的なクラスは、System.Windows.Forms.FolderBrowserDialogです。

C#
using System.Windows.Forms;

FolderBrowserDialogを使うと、ユーザーが選択したフォルダパスをSelectedPathプロパティから取得できます。

1-4. Windows Forms・WPF・.NETの違いに注意

FolderBrowserDialogはWindows Formsのクラスです。

そのため、Windows Formsアプリではそのまま使いやすいですが、WPFアプリで使う場合はSystem.Windows.Formsへの参照が必要になることがあります。

また、.NET Framework.NET Core.NET 5以降ではプロジェクト設定が異なる場合があるため、環境に応じた設定確認も重要です。

2. FolderBrowserDialogを使ったフォルダ選択の実装方法

2-1. FolderBrowserDialogの基本的な使い方

FolderBrowserDialogの基本的な流れは、次のとおりです。

C#
using System.Windows.Forms;

using var dialog = new FolderBrowserDialog();

if (dialog.ShowDialog() == DialogResult.OK)
{
string folderPath = dialog.SelectedPath;
}

ダイアログを表示し、ユーザーがOKを押した場合だけ選択されたフォルダパスを取得します。

2-2. ShowDialogでダイアログを表示する

ShowDialogメソッドを呼び出すと、フォルダ選択ダイアログが表示されます。

C#
dialog.ShowDialog();

ただし、実際には戻り値を使って、ユーザーがOKを押したのかキャンセルしたのかを判定するのが一般的です。

2-3. DialogResult.OKで選択結果を判定する

ユーザーがフォルダを選択してOKを押すと、ShowDialogの戻り値はDialogResult.OKになります。

C#
if (dialog.ShowDialog() == DialogResult.OK)
{
// OKが押された場合の処理
}

キャンセルされた場合は、フォルダパスを使わないようにする必要があります。

2-4. SelectedPathで選択されたフォルダパスを取得する

選択されたフォルダのパスは、SelectedPathプロパティから取得します。

C#
string selectedFolder = dialog.SelectedPath;

取得できる値は、たとえば次のような文字列です。

C:\Users\UserName\Documents

2-5. usingを使ってリソースを適切に解放する

FolderBrowserDialogは使用後に破棄するのが望ましいため、usingを使います。

C#
using var dialog = new FolderBrowserDialog();

古い書き方では、次のようにも書けます。

C#
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string folderPath = dialog.SelectedPath;
}
}

3. FolderBrowserDialogの実装サンプルコード

3-1. 最小構成のサンプルコード

最小構成でフォルダ選択ダイアログを表示するコードは次のとおりです。

C#
using System;
using System.Windows.Forms;

class Program
{
[STAThread]
static void Main()
{
using var dialog = new FolderBrowserDialog();

if (dialog.ShowDialog() == DialogResult.OK)
{
Console.WriteLine(dialog.SelectedPath);
}
}
}

[STAThread]は、WindowsのUI関連処理で必要になることがあるため、コンソールアプリでダイアログを表示する場合は付けておくと安心です。

3-2. ボタンクリックでフォルダ選択ダイアログを開く例

Windows Formsアプリでボタンをクリックしたときにフォルダ選択ダイアログを開く例です。

C#
private void button1_Click(object sender, EventArgs e)
{
using var dialog = new FolderBrowserDialog();

if (dialog.ShowDialog() == DialogResult.OK)
{
MessageBox.Show(dialog.SelectedPath);
}
}

ボタンクリックイベント内でFolderBrowserDialogを作成し、選択されたパスを表示しています。

3-3. TextBoxに選択したフォルダパスを表示する例

選択したフォルダパスをTextBoxに表示する場合は、次のようにします。

C#
private void buttonSelectFolder_Click(object sender, EventArgs e)
{
using var dialog = new FolderBrowserDialog();

if (dialog.ShowDialog() == DialogResult.OK)
{
textBoxFolderPath.Text = dialog.SelectedPath;
}
}

設定画面などで、保存先フォルダをユーザーに指定してもらう場合によく使う実装です。

3-4. キャンセルされた場合の処理

ユーザーがキャンセルした場合は、DialogResult.OKになりません。

C#
using var dialog = new FolderBrowserDialog();

if (dialog.ShowDialog() == DialogResult.OK)
{
textBoxFolderPath.Text = dialog.SelectedPath;
}
else
{
MessageBox.Show("フォルダ選択がキャンセルされました。");
}

キャンセル時にSelectedPathを前提に処理を進めると、不正な処理につながることがあります。

3-5. 選択したフォルダが存在するか確認する方法

選択されたフォルダが存在するか確認するには、Directory.Existsを使います。

C#
using System.IO;

if (Directory.Exists(dialog.SelectedPath))
{
MessageBox.Show("フォルダが存在します。");
}
else
{
MessageBox.Show("フォルダが存在しません。");
}

通常、FolderBrowserDialogで選択されたフォルダは存在しますが、後続処理の前に確認しておくと安全です。

4. FolderBrowserDialogでよく使うプロパティ

4-1. Descriptionで説明文を表示する

Descriptionを設定すると、ダイアログに説明文を表示できます。

C#
using var dialog = new FolderBrowserDialog();
dialog.Description = "保存先フォルダを選択してください。";

ユーザーに何を選択すればよいか伝えたい場合に便利です。

4-2. SelectedPathで初期選択フォルダを指定する

SelectedPathは、選択結果の取得だけでなく、初期選択フォルダの指定にも使えます。

C#
dialog.SelectedPath = @"C:\Users\UserName\Documents";

前回選択したフォルダを初期表示したい場合などに利用します。

4-3. RootFolderで参照開始位置を指定する

RootFolderを使うと、参照できる範囲の起点を指定できます。

C#
dialog.RootFolder = Environment.SpecialFolder.Desktop;

たとえば、デスクトップやマイドキュメントを基準に選択させたい場合に使います。

4-4. ShowNewFolderButtonで新規フォルダ作成ボタンを制御する

ShowNewFolderButtonを使うと、新しいフォルダを作成するボタンを表示するかどうかを制御できます。

C#
dialog.ShowNewFolderButton = true;

既存フォルダだけを選択させたい場合は、次のようにします。

C#
dialog.ShowNewFolderButton = false;

4-5. InitialDirectoryを使える環境と注意点

一部の環境では、FolderBrowserDialogInitialDirectoryプロパティが用意されています。

C#
dialog.InitialDirectory = @"C:\Work";

ただし、使用できるかどうかはターゲットフレームワークやライブラリのバージョンによって異なります。

古い.NET Framework向けのサンプルでは使えない場合があるため、エラーになる場合はSelectedPathで初期フォルダを指定する方法を検討してください。

4-6. Multiselectで複数フォルダ選択を行う方法

環境によっては、Multiselectプロパティを使って複数フォルダ選択に対応できます。

C#
dialog.Multiselect = true;

複数選択されたパスは、対応している環境ではSelectedPathsなどから取得します。

ただし、すべての.NET環境で使えるわけではないため、利用前に対象フレームワークで対応しているか確認が必要です。

4-7. UseDescriptionForTitleでタイトル表示を調整する

UseDescriptionForTitleを使える環境では、Descriptionの内容をダイアログのタイトルとして表示できます。

C#
dialog.Description = "フォルダを選択";
dialog.UseDescriptionForTitle = true;

こちらも環境によって利用可否が異なるため、プロパティが見つからない場合はターゲットフレームワークを確認しましょう。

5. OpenFileDialogでフォルダ選択はできるのか

5-1. OpenFileDialogは本来ファイル選択用のダイアログ

OpenFileDialogは、名前のとおりファイルを選択するためのダイアログです。

C#
using var dialog = new OpenFileDialog();

画像ファイル、CSVファイル、テキストファイルなど、ファイル単体を選ぶ場合に使用します。

5-2. OpenFileDialogとFolderBrowserDialogの違い

OpenFileDialogFolderBrowserDialogの主な違いは、選択対象です。

OpenFileDialogはファイルを選択します。

一方、FolderBrowserDialogはフォルダを選択します。

フォルダパスが必要な場合は、基本的にFolderBrowserDialogを使います。

5-3. FileName・FileNamesとSelectedPathの違い

OpenFileDialogでは、選択されたファイルパスをFileNameで取得します。

C#
string filePath = openFileDialog.FileName;

複数ファイル選択の場合はFileNamesを使います。

C#
string[] filePaths = openFileDialog.FileNames;

一方、FolderBrowserDialogでは、フォルダパスをSelectedPathで取得します。

C#
string folderPath = folderBrowserDialog.SelectedPath;

5-4. ファイル選択とフォルダ選択を混同しやすい理由

ファイルを保存する場所を指定したい場合、ユーザーとしては「フォルダを選びたい」と考えます。

しかし、開発者側ではOpenFileDialogSaveFileDialogFolderBrowserDialogなど複数のダイアログがあるため、混同しやすくなります。

既存ファイルを開くならOpenFileDialog、保存ファイル名を指定するならSaveFileDialog、フォルダだけを選ぶならFolderBrowserDialogと考えると整理しやすいです。

5-5. フォルダ選択にはFolderBrowserDialogを使うべきケース

次のような場合は、FolderBrowserDialogを使うのが適切です。

C#
using var dialog = new FolderBrowserDialog();

フォルダ内のファイルをまとめて処理する場合、保存先ディレクトリを指定する場合、バックアップ先フォルダを指定する場合などです。

5-6. OpenFileDialogを使った代替実装が必要になるケース

古いUIではなく、エクスプローラー風の見た目でフォルダを選ばせたい場合、OpenFileDialogを工夫して使う実装が紹介されることがあります。

ただし、OpenFileDialogは本来ファイル選択用のため、無理にフォルダ選択に使うと実装が複雑になります。

特別な理由がない限り、C#でフォルダ選択を行う場合はFolderBrowserDialogを使う方が分かりやすく安全です。

6. WPFでフォルダ選択ダイアログを使う方法

6-1. WPFでSystem.Windows.Forms.FolderBrowserDialogを利用する方法

WPFには、標準でフォルダ選択専用のダイアログが用意されていない環境があります。

そのため、WPFアプリでもSystem.Windows.Forms.FolderBrowserDialogを使う方法がよく使われます。

C#
using System.Windows.Forms;

WPFアプリからWindows Formsのダイアログを呼び出して、フォルダ選択を実現します。

6-2. 参照設定・usingに必要な名前空間

WPFでFolderBrowserDialogを使うには、次の名前空間を使用します。

C#
using System.Windows.Forms;

ただし、WPFにもSystem.Windows名前空間があるため、MessageBoxなどの名前が競合する場合があります。

その場合は、完全修飾名を使うと安全です。

C#
System.Windows.Forms.FolderBrowserDialog dialog
= new System.Windows.Forms.FolderBrowserDialog();

6-3. WPFのButtonクリックイベントで呼び出すサンプル

WPFのボタンクリックイベントでフォルダ選択ダイアログを表示する例です。

C#
private void SelectFolderButton_Click(object sender, RoutedEventArgs e)
{
using var dialog = new System.Windows.Forms.FolderBrowserDialog();

if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FolderPathTextBox.Text = dialog.SelectedPath;
}
}

WPF側のTextBoxに選択したフォルダパスを表示しています。

6-4. WPFでWindows Formsのダイアログを使う際の注意点

WPFでWindows Formsのダイアログを使う場合、プロジェクト設定によってはビルドエラーになることがあります。

.NET Core.NET 5以降のWPFプロジェクトでは、プロジェクトファイルに次のような設定が必要になる場合があります。

XML
<PropertyGroup>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

また、対象OSがWindowsであることも確認してください。

6-5. Microsoft.Win32.OpenFileDialogとの違い

WPFでは、ファイル選択にMicrosoft.Win32.OpenFileDialogを使うことがあります。

C#
var dialog = new Microsoft.Win32.OpenFileDialog();

これはファイル選択用であり、フォルダ選択用ではありません。

フォルダを選択したい場合は、System.Windows.Forms.FolderBrowserDialogを使うか、対応している環境では別のフォルダ選択APIを検討します。

7. .NET Framework・.NET Core・.NET 5以降での違い

7-1. .NET FrameworkでのFolderBrowserDialogの特徴

.NET Frameworkでは、FolderBrowserDialogは以前からよく使われてきたフォルダ選択用クラスです。

Windows Formsアプリであれば、比較的簡単に利用できます。

C#
using System.Windows.Forms;

ただし、表示されるダイアログの見た目が古いと感じる場合があります。

7-2. .NET Core 3.1以降でのモダンな表示

.NET Core 3.1以降や.NET 5以降では、環境によってより新しい見た目のフォルダ選択ダイアログが表示される場合があります。

ただし、利用できるプロパティや挙動はターゲットフレームワークに依存することがあります。

古い記事のコードをそのまま使うと、プロパティが存在しない、動作が異なるといったことがあるため注意しましょう。

7-3. Windows Formsアプリで使用する場合の注意点

Windows Formsアプリであれば、FolderBrowserDialogは自然に利用できます。

ただし、.NET 5以降のプロジェクトでは、ターゲットフレームワークがWindows向けになっている必要があります。

例として、次のような指定です。

XML
<TargetFramework>net8.0-windows</TargetFramework>

Windows FormsはWindows専用のUI技術であるため、通常のnet8.0ではなくnet8.0-windowsのような指定が必要になることがあります。

7-4. TargetFrameworkやUseWindowsFormsの設定確認

WPFやコンソールアプリでSystem.Windows.Formsを使いたい場合は、プロジェクトファイルを確認します。

XML
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

TargetFrameworkがWindows向けになっているか、UseWindowsFormsが有効になっているかを確認しましょう。

7-5. 古いサンプルコードが動かないときの確認ポイント

古いサンプルコードが動かない場合は、次の点を確認します。

System.Windows.Formsを参照できているか、ターゲットフレームワークがWindows向けか、プロジェクトファイルにUseWindowsFormsが設定されているか、使用しているプロパティが現在の環境で対応しているかを確認してください。

特に、InitialDirectoryMultiselectUseDescriptionForTitleなどは環境によって使えない場合があります。

8. フォルダ選択ダイアログ実装でよくあるエラーと対処法

8-1. FolderBrowserDialogが見つからない場合

FolderBrowserDialogが見つからない場合は、名前空間が不足している可能性があります。

C#
using System.Windows.Forms;

または、完全修飾名で書きます。

C#
var dialog = new System.Windows.Forms.FolderBrowserDialog();

8-2. System.Windows.Formsを参照できない場合

System.Windows.Formsを参照できない場合は、プロジェクト設定を確認します。

.NET 5以降では、次のようにWindows向けのターゲットフレームワークを指定します。

XML
<TargetFramework>net8.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>

WPFプロジェクトでWindows Formsのダイアログを使う場合も、UseWindowsFormsが必要になることがあります。

8-3. 選択したパスが空になる場合

選択したパスが空になる場合は、キャンセル時にもSelectedPathを取得している可能性があります。

必ずDialogResult.OKを確認してから取得します。

C#
if (dialog.ShowDialog() == DialogResult.OK)
{
string path = dialog.SelectedPath;
}

8-4. キャンセル時に例外や不正な処理が起きる場合

キャンセルされた場合は、フォルダパスが選択されていない前提で処理を分けます。

C#
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}

早期リターンを使うと、キャンセル時の処理漏れを防ぎやすくなります。

8-5. 初期フォルダが意図した場所に表示されない場合

初期フォルダが意図した場所に表示されない場合は、指定したパスが存在するか確認します。

C#
string initialPath = @"C:\Work";

if (Directory.Exists(initialPath))
{
dialog.SelectedPath = initialPath;
}

存在しないパスを指定しても、期待どおりに表示されないことがあります。

8-6. WPFでビルドエラーになる場合

WPFでビルドエラーになる場合は、System.Windows.Formsの参照とプロジェクトファイルを確認します。

XML
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>

また、MessageBoxなどのクラス名がWPFとWindows Formsで競合する場合は、名前空間を明示しましょう。

9. フォルダ選択後の実用的な処理

9-1. 選択したフォルダ内のファイル一覧を取得する

選択したフォルダ内のファイル一覧を取得するには、Directory.GetFilesを使います。

C#
string[] files = Directory.GetFiles(dialog.SelectedPath);

foreach (string file in files)
{
Console.WriteLine(file);
}

フォルダ選択後に、その中のファイルを一括処理する場合によく使います。

9-2. 特定の拡張子だけを取得する

特定の拡張子だけを取得するには、検索パターンを指定します。

C#
string[] csvFiles = Directory.GetFiles(dialog.SelectedPath, "*.csv");

画像ファイルを取得する場合は、次のようにできます。

C#
string[] pngFiles = Directory.GetFiles(dialog.SelectedPath, "*.png");

複数の拡張子を扱う場合は、LINQを使う方法もあります。

C#
var imageFiles = Directory.GetFiles(dialog.SelectedPath)
.Where(file => file.EndsWith(".jpg") || file.EndsWith(".png"))
.ToArray();

9-3. サブフォルダを含めて検索する

サブフォルダも含めてファイルを検索するには、SearchOption.AllDirectoriesを指定します。

C#
string[] files = Directory.GetFiles(
dialog.SelectedPath,
"*.txt",
SearchOption.AllDirectories
);

ただし、アクセス権限のないフォルダが含まれると例外が発生する場合があります。

9-4. 選択したフォルダにファイルを保存する

選択したフォルダにファイルを保存するには、Path.Combineを使ってファイルパスを作成します。

C#
string savePath = Path.Combine(dialog.SelectedPath, "sample.txt");

File.WriteAllText(savePath, "保存する内容");

文字列連結でパスを作るより、Path.Combineを使う方が安全です。

9-5. 設定ファイルに前回選択したフォルダを保存する

前回選択したフォルダを保存しておくと、次回起動時に同じ場所を初期表示できます。

C#
Properties.Settings.Default.LastFolderPath = dialog.SelectedPath;
Properties.Settings.Default.Save();

次回表示時には、保存したパスをSelectedPathに設定します。

C#
string lastPath = Properties.Settings.Default.LastFolderPath;

if (Directory.Exists(lastPath))
{
dialog.SelectedPath = lastPath;
}

ユーザーの操作回数を減らせるため、実用的なアプリでは便利な実装です。

9-6. アクセス権限がないフォルダへの対処

選択したフォルダにアクセス権限がない場合、ファイル一覧取得や保存時に例外が発生することがあります。

C#
try
{
string[] files = Directory.GetFiles(dialog.SelectedPath);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("このフォルダにアクセスする権限がありません。");
}
catch (IOException ex)
{
MessageBox.Show($"ファイル操作中にエラーが発生しました: {ex.Message}");
}

フォルダ選択自体は成功しても、その後のファイル操作が必ず成功するとは限りません。

実用的なアプリでは、例外処理を入れておくことが重要です。

まとめ

C#でフォルダ選択ダイアログを実装する場合は、基本的にFolderBrowserDialogを使います。

ShowDialogでダイアログを表示し、DialogResult.OKを確認してから、SelectedPathで選択されたフォルダパスを取得するのが基本的な流れです。

OpenFileDialogはファイル選択用のダイアログであり、フォルダ選択には向いていません。ファイルを選ぶ場合はOpenFileDialog、フォルダを選ぶ場合はFolderBrowserDialogと使い分けましょう。

WPFで使う場合は、System.Windows.Formsの参照やUseWindowsFormsの設定が必要になることがあります。また、.NET Framework.NET Core.NET 5以降では利用できるプロパティや表示の挙動が異なる場合があります。

フォルダ選択後は、Directory.GetFilesでファイル一覧を取得したり、Path.Combineで保存先ファイルパスを作成したりできます。

C#で「フォルダ選択」を実装したい場合は、まずFolderBrowserDialogの基本的な使い方を押さえ、環境に応じてプロジェクト設定やプロパティの違いを確認しながら実装するのがおすすめです。