C# ダイアログの表示方法|MessageBox・ファイル選択・自作まで解説
はじめに
C#でWindowsデスクトップアプリを作るとき、「完了しました」「削除してよいですか?」のような通知や確認、「ファイルを選択してください」「保存先を指定してください」といった操作には、ダイアログがよく使われます。
C#のダイアログには、簡単にメッセージを表示できるMessageBox、ファイルを選択するOpenFileDialog、保存先を選ぶSaveFileDialog、フォルダーを選ぶFolderBrowserDialogやOpenFolderDialog、独自の画面を作る自作ダイアログがあります。
ただし、C#のダイアログはWindows FormsとWPFで使う名前空間や戻り値が異なります。たとえばWinFormsのMessageBox.ShowはSystem.Windows.Forms.DialogResultを返しますが、WPFのMessageBox.ShowはSystem.Windows.MessageBoxResultを返します。Microsoft公式ドキュメントでも、WinForms版のMessageBox.Showはメッセージボックスを表示してDialogResultを返すメソッド、WPF版はMessageBoxResultを返すメソッドとして定義されています。
この記事では、C#でよく使うダイアログの表示方法を、MessageBox、ファイル選択、保存、フォルダー選択、自作ダイアログの順に解説します。
1. C#のダイアログとは?用途と種類を整理
C#のダイアログとは、ユーザーに何かを知らせたり、選択させたり、入力させたりするために表示する小さなウィンドウのことです。
通常の画面とは異なり、ダイアログは「一時的な操作」に向いています。たとえば、アプリケーションのメイン画面とは別に、確認メッセージ、ファイル選択画面、保存先選択画面、設定入力画面などを表示する場合に使います。
1-1. ダイアログはユーザーに通知・確認・入力・選択をさせる画面
C#のダイアログは、主に次のような目的で使われます。
通知だけをしたい場合は、「保存しました」「処理が完了しました」のようなメッセージを表示します。確認をしたい場合は、「削除しますか?」「変更を保存しますか?」のように、ユーザーにOK、Cancel、Yes、Noなどを選ばせます。
ファイルやフォルダーを選ばせたい場合は、標準のファイル選択ダイアログやフォルダー選択ダイアログを使います。ユーザー名、パスワード、検索条件、詳細設定などを入力させたい場合は、自作ダイアログを作ります。
1-2. MessageBox・ファイル選択・フォルダー選択・自作ダイアログの違い
C#でよく使うダイアログには、次のような種類があります。
| 種類 | 主な用途 | 代表的なクラス |
|---|---|---|
| MessageBox | 通知、警告、確認 | MessageBox |
| ファイル選択 | 開くファイルを選ばせる | OpenFileDialog |
| 保存ダイアログ | 保存先とファイル名を選ばせる | SaveFileDialog |
| フォルダー選択 | フォルダーを選ばせる | FolderBrowserDialog、OpenFolderDialog |
| 自作ダイアログ | 独自の入力画面を作る | WinFormsのForm、WPFのWindow |
単純な通知や確認であればMessageBoxだけで十分です。一方、ファイルパスや保存先をユーザーに選ばせる場合は、標準ダイアログを使うほうが自然です。複数の入力欄や独自のレイアウトが必要な場合は、自作ダイアログを作成します。
1-3. Windows FormsとWPFで使うクラスの違い
C#のデスクトップアプリには、主にWindows FormsとWPFがあります。どちらもWindowsデスクトップアプリを作るためのUIフレームワークですが、使うクラスや名前空間が異なります。WPFは.NETの一部として提供されるWindows専用のUIフレームワークです。
WinFormsでよく使うクラスは次のとおりです。
C#using System.Windows.Forms;
MessageBox.Show("メッセージ");
OpenFileDialog openFileDialog = new OpenFileDialog();
SaveFileDialog saveFileDialog = new SaveFileDialog();
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
WPFでよく使うクラスは次のとおりです。
C#using System.Windows;
using Microsoft.Win32;
MessageBox.Show("メッセージ");
OpenFileDialog openFileDialog = new OpenFileDialog();
SaveFileDialog saveFileDialog = new SaveFileDialog();
OpenFolderDialog openFolderDialog = new OpenFolderDialog();
注意点は、MessageBoxやOpenFileDialogという名前が同じでも、WinFormsとWPFでは別のクラスであることです。名前の衝突を避けたい場合は、次のように完全修飾名で書くと安全です。
C#System.Windows.Forms.MessageBox.Show("WinFormsのMessageBox");
System.Windows.MessageBox.Show("WPFのMessageBox");
1-4. モーダルダイアログとモードレスダイアログの違い
ダイアログには、モーダルとモードレスがあります。
モーダルダイアログは、ダイアログを閉じるまで呼び出し元の画面を操作できないダイアログです。MessageBox、OpenFileDialog、SaveFileDialog、FolderBrowserDialog、ShowDialogで表示した自作画面などが代表例です。Microsoft公式ドキュメントでも、FolderBrowserDialogは表示中にアプリケーションの残りの部分がブロックされるモーダルダイアログと説明されています。
モードレスダイアログは、ダイアログを表示したまま呼び出し元の画面も操作できるダイアログです。WinFormsのShow()やWPFのShow()で表示します。検索ウィンドウ、ログ表示ウィンドウ、ツールパレットのように、開いたまま別の操作を続けたい画面に向いています。
2. C#でMessageBoxを表示する基本
C#で最も簡単に使えるダイアログがMessageBoxです。メッセージを表示するだけなら、1行で実装できます。
2-1. MessageBox.Showでメッセージを表示する
WinFormsでメッセージを表示する基本形は次のとおりです。
C#using System.Windows.Forms;
MessageBox.Show("処理が完了しました。");
WPFの場合も書き方は似ています。
C#using System.Windows;
MessageBox.Show("処理が完了しました。");
ただし、使っているMessageBoxの名前空間が違います。WinFormsではSystem.Windows.Forms.MessageBox、WPFではSystem.Windows.MessageBoxです。
WinForms版のMessageBox.Show(string text)は、指定したテキストを含むメッセージボックスを表示し、既定ではOKボタンのみを表示します。
2-2. タイトル・ボタン・アイコンを指定する方法
メッセージだけでなく、タイトル、ボタン、アイコンも指定できます。
WinFormsの場合は次のように書きます。
C#using System.Windows.Forms;
MessageBox.Show(
"ファイルの保存に成功しました。",
"保存完了",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
確認ダイアログにする場合は、MessageBoxButtons.YesNoやMessageBoxIcon.Questionを指定します。
C#DialogResult result = MessageBox.Show(
"データを削除しますか?",
"削除確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
WPFの場合は、MessageBoxButtonとMessageBoxImageを使います。
C#using System.Windows;
MessageBox.Show(
"ファイルの保存に成功しました。",
"保存完了",
MessageBoxButton.OK,
MessageBoxImage.Information
);
確認ダイアログは次のように書きます。
C#MessageBoxResult result = MessageBox.Show(
"データを削除しますか?",
"削除確認",
MessageBoxButton.YesNo,
MessageBoxImage.Question
);
WPF版のMessageBox.Showにも、メッセージ、タイトル、ボタン、アイコンを指定できるオーバーロードがあります。
2-3. OK・Cancel・Yes・Noなどの戻り値を判定する
MessageBox.Showは、ユーザーがどのボタンを押したかを戻り値として返します。
WinFormsではDialogResultを判定します。
C#DialogResult result = MessageBox.Show(
"終了しますか?",
"確認",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question
);
if (result == DialogResult.OK)
{
// OKが押されたときの処理
Close();
}
else
{
// Cancelが押されたときの処理
}
Yes/Noの場合は次のように判定します。
C#DialogResult result = MessageBox.Show(
"削除してもよろしいですか?",
"確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning
);
if (result == DialogResult.Yes)
{
// 削除処理
}
WPFではMessageBoxResultを判定します。
C#MessageBoxResult result = MessageBox.Show(
"終了しますか?",
"確認",
MessageBoxButton.OKCancel,
MessageBoxImage.Question
);
if (result == MessageBoxResult.OK)
{
Close();
}
Yes/Noの場合は次のようにします。
C#MessageBoxResult result = MessageBox.Show(
"削除してもよろしいですか?",
"確認",
MessageBoxButton.YesNo,
MessageBoxImage.Warning
);
if (result == MessageBoxResult.Yes)
{
// 削除処理
}
2-4. エラー・警告・確認メッセージでの使い分け
MessageBoxは便利ですが、すべて同じ見た目にするとユーザーが意味を判断しにくくなります。用途に応じて、タイトル、アイコン、ボタンを使い分けましょう。
エラーの場合は、処理が失敗したことを明確に伝えます。
C#MessageBox.Show(
"ファイルの読み込みに失敗しました。",
"エラー",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
警告の場合は、操作に注意が必要であることを伝えます。
C#MessageBox.Show(
"この操作は元に戻せません。",
"警告",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
確認の場合は、ユーザーに判断させます。
C#DialogResult result = MessageBox.Show(
"変更内容を保存しますか?",
"確認",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question
);
情報通知の場合は、処理完了や案内に使います。
C#MessageBox.Show(
"登録が完了しました。",
"完了",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
2-5. WinFormsとWPFでのMessageBoxの書き方の違い
WinFormsとWPFのMessageBoxは似ていますが、列挙型の名前が違います。
| 項目 | WinForms | WPF |
|---|---|---|
| 名前空間 | System.Windows.Forms | System.Windows |
| 戻り値 | DialogResult | MessageBoxResult |
| ボタン指定 | MessageBoxButtons | MessageBoxButton |
| アイコン指定 | MessageBoxIcon | MessageBoxImage |
WinFormsの例です。
C#System.Windows.Forms.DialogResult result =
System.Windows.Forms.MessageBox.Show(
"削除しますか?",
"確認",
System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question
);
if (result == System.Windows.Forms.DialogResult.Yes)
{
// 削除処理
}
WPFの例です。
C#System.Windows.MessageBoxResult result =
System.Windows.MessageBox.Show(
"削除しますか?",
"確認",
System.Windows.MessageBoxButton.YesNo,
System.Windows.MessageBoxImage.Question
);
if (result == System.Windows.MessageBoxResult.Yes)
{
// 削除処理
}
同じプロジェクトでWinFormsとWPFの名前空間を混在させる場合は、クラス名の衝突に注意してください。
3. C#でファイル選択ダイアログを表示する方法
ファイルを開かせたい場合は、OpenFileDialogを使います。テキストファイル、画像ファイル、CSVファイルなど、ユーザーに既存ファイルを選ばせるときに便利です。
WinForms版のOpenFileDialogは、ファイルを開くようユーザーに求める標準ダイアログボックスを表示するクラスです。 WPFではMicrosoft.Win32.OpenFileDialogを使い、ユーザーが開く1つ以上のファイル名を指定できる共通ダイアログボックスとして定義されています。
3-1. OpenFileDialogでファイルを開くダイアログを表示する
WinFormsでファイル選択ダイアログを表示する基本例です。
C#using System.Windows.Forms;
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "ファイルを選択してください";
if (dialog.ShowDialog() == DialogResult.OK)
{
string filePath = dialog.FileName;
MessageBox.Show(filePath);
}
}
ShowDialog()でダイアログを表示し、戻り値がDialogResult.OKならユーザーがファイルを選択したと判断します。選択されたファイルパスはFileNameで取得します。
WPFの場合は次のように書きます。
C#using Microsoft.Win32;
using System.Windows;
OpenFileDialog dialog = new OpenFileDialog();
dialog.Title = "ファイルを選択してください";
bool? result = dialog.ShowDialog();
if (result == true)
{
string filePath = dialog.FileName;
MessageBox.Show(filePath);
}
WPFのShowDialog()はbool?を返すため、result == trueで判定するのが一般的です。
3-2. Filterで選択できる拡張子を制限する
Filterを設定すると、選択できるファイルの種類を制限できます。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "テキストファイルを選択";
dialog.Filter = "テキストファイル (*.txt)|*.txt|CSVファイル (*.csv)|*.csv|すべてのファイル (*.*)|*.*";
if (dialog.ShowDialog() == DialogResult.OK)
{
string filePath = dialog.FileName;
}
}
Filterは、表示名とパターンを|で区切って書きます。
C#"表示名|拡張子パターン|表示名|拡張子パターン"
たとえば画像ファイルを選ばせる場合は次のようにできます。
C#dialog.Filter = "画像ファイル (*.png;*.jpg;*.jpeg)|*.png;*.jpg;*.jpeg|すべてのファイル (*.*)|*.*";
FilterIndexを使うと、初期選択されるフィルターを指定できます。
C#dialog.FilterIndex = 1;
Microsoft公式ドキュメントの例でも、InitialDirectory、Filter、FilterIndex、RestoreDirectoryを設定してからShowDialog()で表示し、FileNameでパスを取得する流れが示されています。
3-3. 初期フォルダー・タイトル・複数選択を設定する
OpenFileDialogでは、タイトル、初期フォルダー、複数選択などを設定できます。
C#using System;
using System.Windows.Forms;
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "読み込むファイルを選択してください";
dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
dialog.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
dialog.Multiselect = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
string[] filePaths = dialog.FileNames;
foreach (string path in filePaths)
{
// 選択された各ファイルを処理する
}
}
}
InitialDirectoryは最初に表示するフォルダー、Titleはダイアログのタイトル、Multiselectは複数ファイル選択を許可するかどうかです。
複数選択を許可した場合は、FileNameではなくFileNamesを使うと、選択されたすべてのファイルパスを取得できます。
WPFでも同じように設定できます。
C#using Microsoft.Win32;
using System;
OpenFileDialog dialog = new OpenFileDialog
{
Title = "読み込むファイルを選択してください",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*",
Multiselect = true
};
if (dialog.ShowDialog() == true)
{
string[] filePaths = dialog.FileNames;
}
WPF版のOpenFileDialogにも、FileName、FileNames、Filter、InitialDirectory、Multiselectなどのプロパティがあります。
3-4. 選択されたファイルパスを取得する
単一ファイルを選ぶ場合はFileNameを使います。
C#string filePath = dialog.FileName;
ファイル名だけを取り出したい場合は、Path.GetFileNameを使います。
C#using System.IO;
string fileName = Path.GetFileName(filePath);
フォルダー部分だけを取り出したい場合は、Path.GetDirectoryNameを使います。
C#string? directory = Path.GetDirectoryName(filePath);
ファイルを読み込む場合は、選択されたパスを使ってFile.ReadAllTextなどを呼び出します。
C#using System.IO;
using System.Text;
string text = File.ReadAllText(filePath, Encoding.UTF8);
バイナリファイルや画像ファイルの場合は、File.ReadAllBytesや画像ライブラリを使って読み込みます。
3-5. キャンセルされた場合の処理を書く
ファイル選択ダイアログでは、ユーザーがキャンセルする可能性があります。キャンセル時にFileNameをそのまま使うと、空文字や未設定の値を処理してエラーになることがあります。
必ずShowDialog()の戻り値を確認してからFileNameを使いましょう。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "テキストファイル (*.txt)|*.txt";
DialogResult result = dialog.ShowDialog();
if (result != DialogResult.OK)
{
// キャンセルされた場合は何もしない
return;
}
string filePath = dialog.FileName;
string text = File.ReadAllText(filePath);
}
WPFの場合です。
C#OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() != true)
{
return;
}
string filePath = dialog.FileName;
キャンセル時は正常な操作として扱うのが基本です。例外扱いにせず、「何もしない」「前の画面に戻る」「メッセージを出さずに終了する」といった処理にすることが多いです。
4. C#で保存ダイアログを表示する方法
ユーザーに保存先やファイル名を選ばせる場合は、SaveFileDialogを使います。テキストファイルの保存、CSVエクスポート、画像保存、設定ファイルの書き出しなどでよく使います。
WinForms版のSaveFileDialogは、ファイルを保存する場所を選択するようユーザーに求めるクラスです。
4-1. SaveFileDialogで保存先を選択させる
WinFormsで保存ダイアログを表示する基本例です。
C#using System.IO;
using System.Text;
using System.Windows.Forms;
using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Title = "保存先を選択してください";
dialog.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
if (dialog.ShowDialog() == DialogResult.OK)
{
string savePath = dialog.FileName;
File.WriteAllText(savePath, "保存する内容", Encoding.UTF8);
}
}
SaveFileDialogは保存先のパスを決めるためのダイアログです。実際にファイルを書き込む処理は、自分でFile.WriteAllTextやFileStreamなどを使って実装します。
WPFの場合は次のように書きます。
C#using Microsoft.Win32;
using System.IO;
using System.Text;
SaveFileDialog dialog = new SaveFileDialog
{
Title = "保存先を選択してください",
Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*"
};
if (dialog.ShowDialog() == true)
{
string savePath = dialog.FileName;
File.WriteAllText(savePath, "保存する内容", Encoding.UTF8);
}
4-2. デフォルトのファイル名と拡張子を指定する
保存ダイアログでは、初期表示するファイル名や既定の拡張子を指定できます。
C#using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Title = "レポートを保存";
dialog.FileName = "report";
dialog.DefaultExt = "txt";
dialog.Filter = "テキストファイル (*.txt)|*.txt|CSVファイル (*.csv)|*.csv";
if (dialog.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(dialog.FileName, "レポート内容");
}
}
FileNameには初期表示するファイル名を設定します。DefaultExtには、ユーザーが拡張子を省略した場合に使う既定の拡張子を指定します。
拡張子を自動で付けたい場合は、AddExtensionも有効です。
C#dialog.AddExtension = true;
dialog.DefaultExt = "txt";
4-3. 上書き確認や存在チェックを設定する
保存ダイアログでは、上書き確認やパスの存在チェックを設定できます。
C#using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Title = "保存先を選択";
dialog.Filter = "テキストファイル (*.txt)|*.txt";
dialog.FileName = "sample.txt";
dialog.OverwritePrompt = true;
dialog.CheckPathExists = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(dialog.FileName, "内容");
}
}
OverwritePromptをtrueにすると、既存ファイルを選んだときに上書き確認が表示されます。CheckPathExistsをtrueにすると、存在しないパスが指定された場合に警告できます。
多くの場合、これらは既定値のままでも問題ありませんが、保存処理を安全にしたい場合は明示しておくと読みやすくなります。
4-4. 保存先パスを取得してファイルを書き込む
保存ダイアログで重要なのは、「ダイアログは保存先を選ばせるだけ」という点です。ユーザーがOKを押しても、自動的にファイルの内容が保存されるわけではありません。
次のように、FileNameで保存先パスを取得してから書き込みます。
C#using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
private void SaveText(string text)
{
using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Title = "テキストを保存";
dialog.FileName = "memo.txt";
dialog.Filter = "テキストファイル (*.txt)|*.txt|すべてのファイル (*.*)|*.*";
dialog.OverwritePrompt = true;
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
try
{
File.WriteAllText(dialog.FileName, text, Encoding.UTF8);
MessageBox.Show("保存しました。", "完了", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(
$"保存に失敗しました。\n{ex.Message}",
"エラー",
MessageBoxButtons.OK,
MessageBoxIcon.Error
);
}
}
}
ファイル保存では、アクセス権限、パスの長さ、ファイル使用中、ディスク容量不足などで例外が発生する可能性があります。try-catchでエラー処理を書いておくと、アプリが突然終了することを防げます。
5. C#でフォルダー選択ダイアログを表示する方法
フォルダーを選ばせたい場合は、WinFormsではFolderBrowserDialog、WPFでは.NETのバージョンに応じてOpenFolderDialogまたはWinFormsのFolderBrowserDialogを使います。
5-1. FolderBrowserDialogを使う基本
WinFormsでフォルダー選択ダイアログを表示する基本例です。
C#using System.Windows.Forms;
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
dialog.Description = "フォルダーを選択してください";
dialog.ShowNewFolderButton = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
string folderPath = dialog.SelectedPath;
MessageBox.Show(folderPath);
}
}
FolderBrowserDialogは、ユーザーにフォルダーの参照、作成、選択を求めるためのクラスです。ファイルではなくフォルダーを選択させたい場合に使います。
初期選択フォルダーを指定したい場合は、SelectedPathにパスを設定します。
C#using System.IO;
using System.Windows.Forms;
using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
string initialPath = @"C:\Work";
if (Directory.Exists(initialPath))
{
dialog.SelectedPath = initialPath;
}
if (dialog.ShowDialog() == DialogResult.OK)
{
string folderPath = dialog.SelectedPath;
}
}
5-2. 選択されたフォルダーパスを取得する
FolderBrowserDialogで選択されたフォルダーは、SelectedPathで取得します。
C#string selectedFolder = dialog.SelectedPath;
取得したフォルダーパスを使って、配下のファイル一覧を取得できます。
C#using System.IO;
string[] files = Directory.GetFiles(selectedFolder);
サブフォルダーも含めて取得する場合は、次のようにします。
C#string[] files = Directory.GetFiles(
selectedFolder,
"*.*",
SearchOption.AllDirectories
);
ただし、アクセス権限のないフォルダーを含む場合は例外が発生する可能性があります。業務アプリなどでは、try-catchで保護することをおすすめします。
5-3. WPFでフォルダー選択ダイアログを使う方法
WPFでフォルダーを選ばせる場合、Microsoft.Win32.OpenFolderDialogを使える環境ではこれが分かりやすい選択肢です。OpenFolderDialogは、ユーザーが1つ以上のフォルダーを開くことができる共通ダイアログボックスを表し、FolderNameやFolderNames、Multiselectなどのプロパティを持ちます。
C#using Microsoft.Win32;
using System.Windows;
OpenFolderDialog dialog = new OpenFolderDialog
{
Title = "フォルダーを選択してください",
Multiselect = false
};
if (dialog.ShowDialog() == true)
{
string folderPath = dialog.FolderName;
MessageBox.Show(folderPath);
}
複数フォルダーを選ばせる場合は、MultiselectをtrueにしてFolderNamesを使います。
C#OpenFolderDialog dialog = new OpenFolderDialog
{
Title = "フォルダーを選択してください",
Multiselect = true
};
if (dialog.ShowDialog() == true)
{
string[] folderPaths = dialog.FolderNames;
foreach (string path in folderPaths)
{
// 選択された各フォルダーを処理
}
}
WPFでWinFormsのFolderBrowserDialogを使うこともできます。その場合は、プロジェクト設定でWindows Formsを有効にし、System.Windows.Formsを参照できるようにします。
XML<PropertyGroup>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
コードでは完全修飾名で書くと、WPFのMessageBoxなどとの名前衝突を避けられます。
C#using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
dialog.Description = "フォルダーを選択してください";
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string folderPath = dialog.SelectedPath;
}
}
5-4. .NETのバージョンによる使えるダイアログの違い
C#のフォルダー選択ダイアログは、.NETのバージョンによって選択肢が変わります。
WinFormsでは、従来からSystem.Windows.Forms.FolderBrowserDialogがよく使われます。.NET Core 3.1以降のFolderBrowserDialogは、最新のファイルシステムブラウザーウィンドウを使用する、とMicrosoft公式ドキュメントに記載されています。
WPFでは、Microsoft.Win32.OpenFolderDialogを使える環境であれば、WPFらしい書き方でフォルダー選択を実装できます。公式ドキュメント上では、OpenFolderDialogはMicrosoft.Win32名前空間、PresentationFramework.dllに属するクラスとして定義されています。
古い.NET FrameworkのWPFアプリでは、OpenFolderDialogが使えない場合があります。その場合は、WinFormsのFolderBrowserDialogを参照するか、必要に応じて外部ライブラリを検討します。
5-5. OpenFileDialogでフォルダー選択を代用する場合の注意点
古い実装例では、OpenFileDialogを使ってフォルダー選択のように見せる方法が紹介されることがあります。しかし、OpenFileDialogは本来ファイルを選択するためのダイアログです。
フォルダーだけを選ばせたい場合にOpenFileDialogを無理に使うと、次のような問題が起きやすくなります。
ユーザーがファイルを選ばないとOKできない、選択されたファイルからフォルダー名だけを取り出す必要がある、UIとして不自然になる、実装意図がコードから読み取りにくくなる、といった問題です。
フォルダーを選ばせたい場合は、基本的にFolderBrowserDialogまたはOpenFolderDialogを使いましょう。
6. C#で自作ダイアログを作成する方法
標準ダイアログだけでは足りない場合は、自作ダイアログを作ります。たとえば、ユーザー名とパスワードを入力させる画面、検索条件を指定する画面、詳細設定画面などです。
6-1. 自作ダイアログが必要になるケース
自作ダイアログが必要になるのは、標準のMessageBoxやファイル選択ダイアログでは表現できない入力が必要なときです。
たとえば、次のようなケースです。
| ケース | 例 |
|---|---|
| 複数の入力項目がある | 名前、メールアドレス、メモ |
| 入力チェックが必要 | 必須入力、数値範囲、形式チェック |
| 選択肢が複雑 | チェックボックス、ラジオボタン、コンボボックス |
| 独自レイアウトが必要 | 設定画面、検索条件画面 |
| 入力値を呼び出し元に返したい | ユーザーが入力した文字列を取得する |
単純な確認ならMessageBox、ファイルやフォルダーの選択なら標準ダイアログ、独自入力が必要なら自作ダイアログ、という切り分けが基本です。
6-2. WinFormsでフォームを追加してダイアログ化する
WinFormsでは、通常のFormを追加してダイアログとして使えます。
たとえば、名前を入力するInputDialogを作る場合を考えます。
C#using System.Windows.Forms;
public partial class InputDialog : Form
{
public string InputText
{
get { return textBoxName.Text; }
}
public InputDialog()
{
InitializeComponent();
this.Text = "名前の入力";
this.FormBorderStyle = FormBorderStyle.FixedDialog;
this.StartPosition = FormStartPosition.CenterParent;
this.MinimizeBox = false;
this.MaximizeBox = false;
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOk;
this.CancelButton = buttonCancel;
}
}
フォーム上には、TextBox、OKボタン、Cancelボタンを配置しておきます。
ポイントは、OKボタンにDialogResult.OK、CancelボタンにDialogResult.Cancelを設定することです。これにより、呼び出し元でどちらのボタンが押されたかを判定できます。
6-3. ShowDialogで自作フォームをモーダル表示する
作成したフォームは、ShowDialog()で表示します。
C#using (InputDialog dialog = new InputDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
string name = dialog.InputText;
MessageBox.Show($"入力された名前: {name}");
}
}
ShowDialog(this)のように親フォームを指定すると、親子関係が安定します。ダイアログが親フォームの背面に隠れにくくなり、中央表示もしやすくなります。
6-4. DialogResultでOK・Cancelを返す
自作ダイアログでは、DialogResultを使って結果を返すのが基本です。
OKボタンのクリックイベントで入力チェックを行う場合は、次のように書けます。
C#private void buttonOk_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show(
"名前を入力してください。",
"入力エラー",
MessageBoxButtons.OK,
MessageBoxIcon.Warning
);
return;
}
this.DialogResult = DialogResult.OK;
this.Close();
}
Cancelボタンは、単純に閉じるだけで十分です。
C#private void buttonCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
6-5. 入力値を呼び出し元フォームへ渡す
入力値を呼び出し元に渡すには、自作ダイアログ側に読み取り用プロパティを用意します。
C#public string UserName
{
get { return textBoxName.Text; }
}
呼び出し元では、ShowDialog()の結果がOKだった場合だけ値を取得します。
C#using (InputDialog dialog = new InputDialog())
{
DialogResult result = dialog.ShowDialog(this);
if (result == DialogResult.OK)
{
string userName = dialog.UserName;
labelName.Text = userName;
}
}
キャンセルされた場合は値を使わないようにします。キャンセル時にも値を読み取ってしまうと、途中入力の値を誤って反映する可能性があります。
6-6. WPFでWindowを使って自作ダイアログを作る
WPFでは、Windowを追加して自作ダイアログを作ります。
たとえば、InputDialog.xamlを次のように作ります。
XML<Window x:Class="SampleApp.InputDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="名前の入力"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
ResizeMode="NoResize">
<StackPanel Margin="20">
<TextBlock Text="名前を入力してください。" Margin="0,0,0,8" />
<TextBox x:Name="NameTextBox" Width="250" Margin="0,0,0,16" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="OK" Width="80" Margin="0,0,8,0"
IsDefault="True" Click="OkButton_Click" />
<Button Content="Cancel" Width="80"
IsCancel="True" />
</StackPanel>
</StackPanel>
</Window>
コードビハインドは次のようにします。
C#using System.Windows;
namespace SampleApp
{
public partial class InputDialog : Window
{
public string InputText => NameTextBox.Text;
public InputDialog()
{
InitializeComponent();
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(NameTextBox.Text))
{
MessageBox.Show(
this,
"名前を入力してください。",
"入力エラー",
MessageBoxButton.OK,
MessageBoxImage.Warning
);
return;
}
DialogResult = true;
}
}
}
呼び出し元では次のように表示します。
C#InputDialog dialog = new InputDialog();
dialog.Owner = this;
if (dialog.ShowDialog() == true)
{
string name = dialog.InputText;
MessageBox.Show($"入力された名前: {name}");
}
WPFではDialogResultがbool?です。OKならtrue、Cancelや閉じるボタンならfalseまたはnullとして扱います。
7. ShowDialogの使い方と戻り値の扱い
C#のダイアログ実装では、Show()とShowDialog()の違いを理解しておくことが重要です。
7-1. ShowとShowDialogの違い
Show()はモードレス表示です。ウィンドウを表示したあとも、呼び出し元の処理はすぐに次へ進みます。表示したウィンドウを開いたまま、元の画面も操作できます。
C#Form subForm = new SubForm();
subForm.Show();
WPFでも同様です。
C#SubWindow window = new SubWindow();
window.Show();
一方、ShowDialog()はモーダル表示です。ダイアログを閉じるまで、呼び出し元の処理はそこで待機します。
C#using (InputDialog dialog = new InputDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
// ダイアログが閉じた後に実行される
}
}
ユーザーに入力や確認を完了させてから次の処理へ進みたい場合は、ShowDialog()を使います。
7-2. DialogResultの基本的な判定方法
WinFormsでは、ShowDialog()の戻り値をDialogResultで判定します。
C#DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
// OK
}
else if (result == DialogResult.Cancel)
{
// Cancel
}
MessageBoxも同じくDialogResultを返します。
C#DialogResult result = MessageBox.Show(
"保存しますか?",
"確認",
MessageBoxButtons.YesNoCancel
);
switch (result)
{
case DialogResult.Yes:
// 保存する
break;
case DialogResult.No:
// 保存しない
break;
case DialogResult.Cancel:
// キャンセル
break;
}
WPFでは、ShowDialog()はbool?、MessageBox.Show()はMessageBoxResultを返します。
C#if (dialog.ShowDialog() == true)
{
// OK
}
C#MessageBoxResult result = MessageBox.Show(
"保存しますか?",
"確認",
MessageBoxButton.YesNoCancel
);
if (result == MessageBoxResult.Yes)
{
// 保存する
}
7-3. ダイアログを閉じた後に処理を続ける書き方
ダイアログの後続処理は、必ず戻り値を確認してから書きます。
悪い例です。
C#OpenFileDialog dialog = new OpenFileDialog();
dialog.ShowDialog();
string path = dialog.FileName;
LoadFile(path);
この書き方だと、ユーザーがキャンセルしてもLoadFileが呼ばれる可能性があります。
良い例です。
C#OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() != true)
{
return;
}
string path = dialog.FileName;
LoadFile(path);
WinFormsの場合です。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
string path = dialog.FileName;
LoadFile(path);
}
ダイアログは、ユーザーが必ずOKするとは限りません。キャンセル、閉じるボタン、Escキーなどの操作を前提にコードを書くことが大切です。
7-4. 親ウィンドウを指定して表示位置や操作制御を安定させる
ダイアログを表示するときは、できるだけ親ウィンドウを指定しましょう。
WinFormsでは、ShowDialog(this)のように指定します。
C#using (InputDialog dialog = new InputDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
string value = dialog.InputText;
}
}
MessageBoxでも親を指定できます。
C#MessageBox.Show(
this,
"保存しました。",
"完了",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
WPFでは、Ownerを設定するか、MessageBox.Show(this, ...)のように親ウィンドウを渡します。WPF版のMessageBox.Showには、指定したウィンドウの前にメッセージボックスを表示するオーバーロードがあります。
C#InputDialog dialog = new InputDialog();
dialog.Owner = this;
if (dialog.ShowDialog() == true)
{
string value = dialog.InputText;
}
C#MessageBox.Show(
this,
"保存しました。",
"完了",
MessageBoxButton.OK,
MessageBoxImage.Information
);
親ウィンドウを指定すると、ダイアログが背面に隠れにくくなり、モーダル制御も安定します。
8. C#ダイアログ実装でよくあるエラーと対処法
C#でダイアログを実装していると、名前空間の不足、参照設定の不足、キャンセル処理漏れ、ファイルアクセス権限などでエラーが起きることがあります。
8-1. MessageBoxやOpenFileDialogが見つからない場合
MessageBoxやOpenFileDialogが見つからない場合は、まずusingを確認します。
WinFormsの場合です。
C#using System.Windows.Forms;
WPFの場合です。
C#using System.Windows;
using Microsoft.Win32;
ただし、WinFormsとWPFを混在させている場合は、同じMessageBoxという名前で衝突することがあります。その場合は完全修飾名で書きます。
C#System.Windows.Forms.MessageBox.Show("WinForms");
System.Windows.MessageBox.Show("WPF");
OpenFileDialogも同様です。
C#System.Windows.Forms.OpenFileDialog winFormsDialog =
new System.Windows.Forms.OpenFileDialog();
Microsoft.Win32.OpenFileDialog wpfDialog =
new Microsoft.Win32.OpenFileDialog();
8-2. System.Windows.Formsの参照・usingが不足している場合
WPFプロジェクトでWinFormsのFolderBrowserDialogを使いたい場合、using System.Windows.Forms;を追加するだけでは足りないことがあります。
.NETのSDKスタイルプロジェクトでは、.csprojに次の設定を追加します。
XML<PropertyGroup>
<UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
そのうえで、コードでは次のように書きます。
C#using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = dialog.SelectedPath;
}
}
名前空間を大量にusingするより、WinFormsのダイアログだけ完全修飾名で書くほうが、WPFとの衝突を避けやすいです。
8-3. WPFでWinFormsのダイアログを使う場合の注意点
WPFでWinFormsのダイアログを使うこと自体は可能ですが、いくつか注意点があります。
まず、戻り値がWPFのbool?ではなく、WinFormsのDialogResultになります。
C#var dialog = new System.Windows.Forms.FolderBrowserDialog();
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string path = dialog.SelectedPath;
}
また、System.Windows.MessageBoxとSystem.Windows.Forms.MessageBoxが衝突しやすくなります。WPF画面ではWPF版のMessageBoxを使い、WinFormsのダイアログだけ完全修飾名で使うと分かりやすくなります。
さらに、WPFの親ウィンドウとWinFormsのIWin32Windowはそのまま同じ型ではありません。必要に応じて親指定なしで表示するか、WindowInteropHelperを使ってハンドルを渡す方法を検討します。通常の小規模なフォルダー選択であれば、親指定なしでも動作することが多いですが、本格的なアプリでは親子関係を明示したほうが安全です。
8-4. キャンセル時に例外や空文字でエラーになる場合
ダイアログで最も多いミスは、キャンセルされた場合を考慮していないことです。
悪い例です。
C#OpenFileDialog dialog = new OpenFileDialog();
dialog.ShowDialog();
string text = File.ReadAllText(dialog.FileName);
キャンセルされた場合、FileNameが期待どおりのパスにならず、例外が発生する可能性があります。
良い例です。
C#OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() != true)
{
return;
}
string text = File.ReadAllText(dialog.FileName);
WinFormsの場合です。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
string text = File.ReadAllText(dialog.FileName);
}
キャンセルはエラーではなく、ユーザーの通常操作です。戻り値を確認してから処理を続けましょう。
8-5. ファイルパスの扱いで文字化け・アクセス拒否が起きる場合
ファイルパスやファイル内容を扱うときは、文字コードとアクセス権限に注意します。
テキストファイルをUTF-8で読み書きする場合は、明示的にEncoding.UTF8を指定すると意図が分かりやすくなります。
C#string text = File.ReadAllText(path, Encoding.UTF8);
File.WriteAllText(path, text, Encoding.UTF8);
アクセス拒否が起きる場合は、管理者権限が必要なフォルダー、他のアプリが使用中のファイル、読み取り専用ファイル、ネットワークドライブの権限などが原因として考えられます。
保存処理では、必ず例外処理を書きましょう。
C#try
{
File.WriteAllText(path, text, Encoding.UTF8);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("この場所に保存する権限がありません。");
}
catch (IOException ex)
{
MessageBox.Show($"ファイルの保存に失敗しました。\n{ex.Message}");
}
また、パスの結合には文字列連結ではなくPath.Combineを使うのが安全です。
C#string filePath = Path.Combine(folderPath, "sample.txt");
9. 目的別:C#ダイアログの選び方
C#のダイアログは種類が多いため、目的に応じて選ぶことが大切です。
9-1. 通知や確認だけならMessageBox
処理完了、エラー表示、削除確認など、短いメッセージを表示するだけならMessageBoxが最適です。
C#MessageBox.Show("処理が完了しました。");
確認が必要な場合は、Yes/NoやOK/Cancelを使います。
C#DialogResult result = MessageBox.Show(
"削除しますか?",
"確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
ただし、入力欄を置いたり、複雑な選択肢を表示したりする用途には向いていません。
9-2. ファイルを開かせたいならOpenFileDialog
既存ファイルを選ばせたい場合はOpenFileDialogを使います。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "CSVファイル (*.csv)|*.csv";
if (dialog.ShowDialog() == DialogResult.OK)
{
string path = dialog.FileName;
}
}
拡張子を制限したい、複数ファイルを選ばせたい、初期フォルダーを指定したい、といった場合にも対応できます。
9-3. ファイルを保存させたいならSaveFileDialog
ユーザーに保存先を選ばせたい場合はSaveFileDialogを使います。
C#using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.FileName = "export.csv";
dialog.Filter = "CSVファイル (*.csv)|*.csv";
if (dialog.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(dialog.FileName, csvText, Encoding.UTF8);
}
}
保存ダイアログは保存先を決めるだけなので、ファイルを書き込む処理は自分で実装します。
9-4. フォルダーを選ばせたいならFolderBrowserDialogまたはOpenFolderDialog
WinFormsならFolderBrowserDialogが基本です。
C#using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string folder = dialog.SelectedPath;
}
}
WPFでOpenFolderDialogを使える環境なら、次のように書けます。
C#OpenFolderDialog dialog = new OpenFolderDialog
{
Title = "フォルダーを選択してください"
};
if (dialog.ShowDialog() == true)
{
string folder = dialog.FolderName;
}
フォルダー選択をOpenFileDialogで代用するのは、ユーザー体験やコードの分かりやすさの面でおすすめしません。
9-5. 独自の入力画面が必要なら自作ダイアログ
ユーザーに複数項目を入力させたい場合や、独自のレイアウトが必要な場合は自作ダイアログを使います。
WinFormsならForm、WPFならWindowを作成してShowDialog()で表示します。
C#using (InputDialog dialog = new InputDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
string value = dialog.InputText;
}
}
自作ダイアログでは、入力チェック、OK/Cancelの戻り値、呼び出し元への値の受け渡しを設計することが重要です。
10. C#ダイアログに関するよくある質問
C#のダイアログ実装でよくある疑問をまとめます。
10-1. C#で確認ダイアログを出すには?
確認ダイアログはMessageBox.Showでボタンを指定して表示します。
WinFormsの場合です。
C#DialogResult result = MessageBox.Show(
"削除しますか?",
"確認",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question
);
if (result == DialogResult.OK)
{
// OK時の処理
}
WPFの場合です。
C#MessageBoxResult result = MessageBox.Show(
"削除しますか?",
"確認",
MessageBoxButton.OKCancel,
MessageBoxImage.Question
);
if (result == MessageBoxResult.OK)
{
// OK時の処理
}
10-2. MessageBoxのボタンをYes/Noにするには?
WinFormsではMessageBoxButtons.YesNoを指定します。
C#DialogResult result = MessageBox.Show(
"保存しますか?",
"確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
if (result == DialogResult.Yes)
{
// Yes
}
WPFではMessageBoxButton.YesNoを指定します。
C#MessageBoxResult result = MessageBox.Show(
"保存しますか?",
"確認",
MessageBoxButton.YesNo,
MessageBoxImage.Question
);
if (result == MessageBoxResult.Yes)
{
// Yes
}
10-3. OpenFileDialogで複数ファイルを選択するには?
Multiselectをtrueにします。選択された複数ファイルはFileNamesで取得します。
C#using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Multiselect = true;
dialog.Filter = "画像ファイル (*.png;*.jpg)|*.png;*.jpg";
if (dialog.ShowDialog() == DialogResult.OK)
{
foreach (string path in dialog.FileNames)
{
// 各ファイルを処理
}
}
}
WPFでも同じ考え方です。
C#OpenFileDialog dialog = new OpenFileDialog
{
Multiselect = true
};
if (dialog.ShowDialog() == true)
{
string[] paths = dialog.FileNames;
}
10-4. ダイアログの初期フォルダーを指定するには?
ファイル選択や保存ダイアログでは、InitialDirectoryを使います。
C#dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
フォルダー選択のFolderBrowserDialogでは、初期選択としてSelectedPathを設定します。
C#dialog.SelectedPath = @"C:\Work";
WPFのOpenFolderDialogでは、InitialDirectoryやFolderNameを使って初期位置を指定できます。
C#OpenFolderDialog dialog = new OpenFolderDialog
{
InitialDirectory = @"C:\Work",
FolderName = @"C:\Work"
};
10-5. WPFとWinFormsで同じコードは使える?
完全に同じコードは使えないことが多いです。
たとえば、WinFormsのMessageBox.ShowはDialogResultを返しますが、WPFのMessageBox.ShowはMessageBoxResultを返します。ボタンやアイコンの列挙型も、WinFormsではMessageBoxButtons、MessageBoxIcon、WPFではMessageBoxButton、MessageBoxImageです。
また、ファイル選択ダイアログも、WinFormsではSystem.Windows.Forms.OpenFileDialog、WPFではMicrosoft.Win32.OpenFileDialogを使うのが一般的です。
共通化したい場合は、ダイアログ処理をラッパークラスに分けるとよいでしょう。
C#public interface IDialogService
{
bool Confirm(string message);
void ShowInfo(string message);
}
UIフレームワークごとに実装を分ければ、アプリ本体のロジックからWinFormsやWPFへの依存を減らせます。
10-6. 自作ダイアログから値を返すには?
自作ダイアログ側にプロパティを用意し、OKが押された場合だけ呼び出し元で値を取得します。
WinFormsの例です。
C#public string InputText => textBoxInput.Text;
呼び出し元です。
C#using (InputDialog dialog = new InputDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
{
string value = dialog.InputText;
}
}
WPFの例です。
C#public string InputText => InputTextBox.Text;
呼び出し元です。
C#InputDialog dialog = new InputDialog();
dialog.Owner = this;
if (dialog.ShowDialog() == true)
{
string value = dialog.InputText;
}
重要なのは、キャンセル時には値を使わないことです。ShowDialog()の戻り値を確認し、OKの場合だけプロパティを読み取るようにしましょう。
まとめ
C#のダイアログは、ユーザーに通知、確認、入力、選択をしてもらうための重要なUIです。
通知や簡単な確認にはMessageBox、ファイルを開くにはOpenFileDialog、保存先を選ばせるにはSaveFileDialog、フォルダーを選ばせるにはFolderBrowserDialogまたはOpenFolderDialog、独自の入力画面が必要な場合は自作ダイアログを使います。
WinFormsとWPFでは、同じような名前のクラスでも名前空間や戻り値が異なります。WinFormsではDialogResult、WPFではMessageBoxResultやbool?を使う場面が多いため、サンプルコードを流用するときは対象のUIフレームワークを確認しましょう。
また、ダイアログではユーザーがキャンセルすることを前提に実装することが大切です。ShowDialog()の戻り値を確認してから、ファイルパスや入力値を使うようにすれば、空文字や未選択によるエラーを防げます。
C#でダイアログを正しく使えるようになると、ユーザーにとって分かりやすく、安全に操作できるWindowsアプリを作りやすくなります。

