C# DialogResultの使い方完全ガイド|ShowDialogの戻り値・OK/Cancel判定・閉じ方まで解説
はじめに
C#でWindowsフォームアプリケーションを作成していると、確認画面や入力画面を表示して「OKが押されたか」「Cancelされたか」を判定したい場面がよくあります。
そのときに使うのがDialogResultです。
DialogResultを正しく使うと、次のような処理をシンプルに書けます。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// OKが押されたときだけ処理する
}
}
一方で、Show()とShowDialog()の違い、ボタンのDialogResultプロパティ、Close()との関係、×ボタンで閉じたときの戻り値などでつまずくことも少なくありません。
この記事では、C#のDialogResultの基本から、ShowDialogの戻り値の判定、OK/Cancelボタンの作り方、入力フォームでの実践例、MessageBoxでの使い方、うまく動かないときの原因まで詳しく解説します。
1. C#のDialogResultとは?まず押さえる基本
1-1. DialogResultはダイアログの操作結果を表す戻り値
DialogResultは、ダイアログ画面に対してユーザーがどの操作をしたかを表す値です。
たとえば、次のような結果を表します。
C#DialogResult.OK
DialogResult.Cancel
DialogResult.Yes
DialogResult.No
「OKボタンが押された」「キャンセルされた」「はいが選ばれた」「いいえが選ばれた」といった操作結果を、親フォーム側で判定するために使います。
代表的な用途は次の2つです。
C#// 自作フォームの結果を判定する
if (form.ShowDialog() == DialogResult.OK)
{
// OK時の処理
}
// MessageBoxの結果を判定する
if (MessageBox.Show("削除しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// Yes時の処理
}
DialogResultは、ダイアログを表示するだけでなく、その結果に応じて処理を分岐させるための重要な仕組みです。
1-2. ShowDialogとDialogResultの関係
フォームをダイアログとして表示するときは、ShowDialog()を使います。
C#Form2 form = new Form2();
DialogResult result = form.ShowDialog();
ShowDialog()は、表示したフォームが閉じられるまで呼び出し元の処理を一時停止します。
そして、フォームが閉じられたあとに、そのフォームのDialogResultを戻り値として返します。
C#DialogResult result = form.ShowDialog();
if (result == DialogResult.OK)
{
// OKが押された
}
else if (result == DialogResult.Cancel)
{
// Cancelが押された
}
つまり、ShowDialog()とDialogResultはセットで使うことが多いです。
ShowDialog()で子フォームを開き、閉じたあとに戻り値を見て、親フォーム側で処理を決めるのが基本です。
1-3. MessageBoxのDialogResultとフォームのDialogResultの違い
DialogResultは、主に次の2つの場面で使われます。
1つ目は、MessageBox.Show()の戻り値です。
C#DialogResult result = MessageBox.Show(
"保存しますか?",
"確認",
MessageBoxButtons.YesNoCancel
);
この場合、ユーザーがメッセージボックスで押したボタンに応じて、DialogResult.YesやDialogResult.Noなどが返ります。
2つ目は、自作フォームをShowDialog()で表示したときの戻り値です。
C#using (var form = new SettingsForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// 設定を反映する
}
}
この場合は、自作フォーム内のボタンやコードで設定したDialogResultが、ShowDialog()の戻り値になります。
どちらもDialogResultを使いますが、意味は少し異なります。
MessageBoxでは、ユーザーが押した標準ボタンの結果です。
自作フォームでは、開発者がフォームやボタンに設定した結果です。
1-4. よく使うDialogResultの種類一覧(OK/Cancel/Yes/Noなど)
DialogResultには、よく使われる値がいくつかあります。
C#DialogResult.None
DialogResult.OK
DialogResult.Cancel
DialogResult.Abort
DialogResult.Retry
DialogResult.Ignore
DialogResult.Yes
DialogResult.No
よく使うものは、主に次の4つです。
C#DialogResult.OK // OK
DialogResult.Cancel // キャンセル
DialogResult.Yes // はい
DialogResult.No // いいえ
入力フォームでは、OKとCancelを使うことが多いです。
確認メッセージでは、YesとNoを使うことが多いです。
たとえば、入力ダイアログでは次のように判定します。
C#if (form.ShowDialog() == DialogResult.OK)
{
// 入力内容を使う
}
削除確認では、次のように判定します。
C#if (MessageBox.Show("削除しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// 削除する
}
2. ShowDialogの戻り値でOK・Cancelを判定する基本コード
2-1. ShowDialogの戻り値をif文で判定する
ShowDialog()の戻り値はDialogResult型です。
そのため、次のようにif文で判定できます。
C#using (var dialog = new SampleDialog())
{
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
MessageBox.Show("OKが押されました");
}
else if (result == DialogResult.Cancel)
{
MessageBox.Show("キャンセルされました");
}
}
より短く書くなら、次のように直接比較しても構いません。
C#using (var dialog = new SampleDialog())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("OKが押されました");
}
}
実務では、OKが押されたときだけ処理したいケースが多いため、この書き方がよく使われます。
2-2. OKが押されたときだけ処理を実行する
入力フォームや設定画面では、ユーザーがOKを押したときだけ値を反映したいことがよくあります。
C#using (var dialog = new SettingsForm())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
// OK時だけ設定を反映する
string userName = dialog.UserName;
MessageBox.Show($"入力された名前: {userName}");
}
}
このコードでは、SettingsFormがDialogResult.OKを返した場合だけ、入力値を取得しています。
Cancelや×ボタンで閉じられた場合は、何も処理しません。
このように、DialogResult.OKを条件にすることで、ユーザーが確定した場合だけ処理を進められます。
2-3. Cancelまたは閉じるボタンが押されたときの処理
Cancelや×ボタンで閉じられた場合も処理したいときは、elseやelse ifを使います。
C#using (var dialog = new SampleDialog())
{
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
MessageBox.Show("処理を実行します");
}
else
{
MessageBox.Show("処理をキャンセルしました");
}
}
Cancelだけを明確に判定したい場合は、次のように書きます。
C#using (var dialog = new SampleDialog())
{
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.Cancel)
{
MessageBox.Show("キャンセルされました");
}
}
ただし、×ボタンで閉じた場合の戻り値は、フォームの設定や閉じ方によって意識が必要です。
一般的には、OK以外はキャンセル扱いにする実装が安全です。
C#if (dialog.ShowDialog() != DialogResult.OK)
{
// OK以外はキャンセル扱い
return;
}
2-4. usingを使ったダイアログフォームの安全な表示方法
自作フォームをShowDialog()で表示したあとは、使い終わったフォームを破棄する必要があります。
そのため、次のようにusingを使う書き方がよく使われます。
C#using (var dialog = new InputForm())
{
if (dialog.ShowDialog() == DialogResult.OK)
{
string value = dialog.InputText;
MessageBox.Show(value);
}
}
usingを使うと、ブロックを抜けるときに自動でDispose()が呼ばれます。
これにより、フォームが保持していたリソースを適切に解放できます。
特に、ダイアログフォームを何度も表示するアプリでは、usingを使って安全に破棄する習慣をつけておくとよいでしょう。
3. DialogResult.OKを返すダイアログフォームの作り方
3-1. ボタンのDialogResultプロパティを設定する方法
Windowsフォームのボタンには、DialogResultプロパティがあります。
OKボタンに次のように設定できます。
C#buttonOK.DialogResult = DialogResult.OK;
Cancelボタンには、次のように設定します。
C#buttonCancel.DialogResult = DialogResult.Cancel;
デザイナー画面でも設定できます。
ボタンを選択し、プロパティウィンドウからDialogResultをOKやCancelに変更します。
この設定をしておくと、ボタンがクリックされたときにフォームのDialogResultが設定され、モーダルダイアログが閉じられます。
3-2. OKボタンとCancelボタンをフォームに配置する
基本的なダイアログフォームでは、OKボタンとCancelボタンを配置します。
コードで設定する場合は、次のようになります。
C#public partial class InputForm : Form
{
public InputForm()
{
InitializeComponent();
buttonOK.Text = "OK";
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.Text = "キャンセル";
buttonCancel.DialogResult = DialogResult.Cancel;
}
}
親フォーム側では、次のように判定します。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("OKが押されました");
}
}
OKボタンとCancelボタンのDialogResultを設定しておけば、複雑なクリックイベントを書かなくても基本的なダイアログ処理を実現できます。
3-3. AcceptButtonとCancelButtonの設定
フォームには、AcceptButtonとCancelButtonというプロパティがあります。
AcceptButtonは、Enterキーが押されたときに実行されるボタンです。
CancelButtonは、Escキーが押されたときに実行されるボタンです。
C#public InputForm()
{
InitializeComponent();
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
}
この設定により、ユーザーはマウスでボタンをクリックしなくても、EnterキーでOK、EscキーでCancelを実行できます。
入力ダイアログでは、操作性を高めるために設定しておくと便利です。
3-4. Enterキー・EscキーでOK/Cancelを実行する方法
EnterキーでOK、EscキーでCancelを動かすには、次の3つを設定します。
C#buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
完全な例は次のとおりです。
C#public partial class InputForm : Form
{
public InputForm()
{
InitializeComponent();
buttonOK.Text = "OK";
buttonCancel.Text = "キャンセル";
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
}
}
これで、ユーザーがEnterキーを押すとOKボタンを押したのと同じ扱いになり、Escキーを押すとCancelボタンを押したのと同じ扱いになります。
4. ダイアログを閉じる方法とDialogResultの設定
4-1. ボタンクリックでDialogResultを設定して閉じる
ボタンクリックイベント内で、明示的にDialogResultを設定することもできます。
C#private void buttonOK_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
Cancelの場合は次のようにします。
C#private void buttonCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
ShowDialog()で表示されているフォームでは、DialogResultにOKやCancelなどを設定すると、通常はフォームが閉じられます。
そのため、次のように親フォーム側で結果を受け取れます。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("OKで閉じました");
}
}
4-2. Closeメソッドとの違い
Close()はフォームを閉じるためのメソッドです。
C#private void buttonClose_Click(object sender, EventArgs e)
{
this.Close();
}
一方、DialogResultは「どの結果で閉じたか」を表す値です。
たとえば、次のコードではフォームは閉じますが、親フォーム側でOKが押されたとは判定できない場合があります。
C#private void buttonOK_Click(object sender, EventArgs e)
{
this.Close();
}
OKとして扱いたいなら、Close()だけではなくDialogResultを設定する必要があります。
C#private void buttonOK_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
または、ボタンのDialogResultプロパティをOKに設定します。
C#buttonOK.DialogResult = DialogResult.OK;
ダイアログでは、「閉じる」だけでなく「どの結果で閉じるか」を明確にすることが重要です。
4-3. DialogResultを設定すると自動で閉じる仕組み
フォームをShowDialog()で表示している場合、フォームのDialogResultにNone以外の値を設定すると、ダイアログは閉じられます。
C#this.DialogResult = DialogResult.OK;
そのため、基本的には次のようにClose()を追加しなくても構いません。
C#private void buttonOK_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.OK;
}
ただし、入力チェックを行う場合は注意が必要です。
たとえば、入力に問題がある場合は、OKで閉じずに画面を残したいことがあります。
その場合は、すぐにDialogResult.OKを設定せず、入力チェックに成功したときだけ設定します。
C#private void buttonOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください");
return;
}
this.DialogResult = DialogResult.OK;
}
4-4. 閉じるボタン(×)を押したときのDialogResult
フォーム右上の×ボタンを押して閉じた場合、OKボタンを押したわけではないため、通常はOKとして扱いません。
親フォーム側では、OK以外をキャンセル扱いにする書き方が安全です。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// OK時の処理
}
else
{
// Cancelまたは×ボタンで閉じた場合
}
}
×ボタンを明確にCancel扱いにしたい場合は、フォームのFormClosingイベントなどで制御する方法もあります。
ただし、多くの場合は、親フォーム側で次のように判定すれば十分です。
C#if (form.ShowDialog() != DialogResult.OK)
{
return;
}
この書き方なら、Cancelボタンでも×ボタンでも、OK以外はすべて処理を中断できます。
5. 入力フォームでDialogResultを使う実践例
5-1. 子フォームで入力された値を親フォームに渡す
自作の入力フォームでは、子フォームで入力された値を親フォームに渡すことがよくあります。
この場合、子フォーム側にプロパティを用意します。
C#public partial class InputForm : Form
{
public string InputText
{
get { return textBoxInput.Text; }
}
public InputForm()
{
InitializeComponent();
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
}
}
親フォーム側では、ShowDialog()の戻り値がDialogResult.OKだったときだけ、入力値を取得します。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string text = form.InputText;
MessageBox.Show($"入力値: {text}");
}
}
この形にすると、Cancelや×ボタンで閉じた場合に入力値を使わずに済みます。
5-2. OK時だけ入力値を取得するサンプルコード
実用的な例として、名前を入力するダイアログを考えます。
子フォーム側のコードです。
C#public partial class NameInputForm : Form
{
public string UserName
{
get { return textBoxName.Text; }
}
public NameInputForm()
{
InitializeComponent();
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
}
}
親フォーム側のコードです。
C#private void buttonOpenDialog_Click(object sender, EventArgs e)
{
using (var form = new NameInputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string name = form.UserName;
labelResult.Text = name;
}
}
}
このコードでは、OKが押されたときだけlabelResultに入力値を反映します。
Cancelが押された場合や、×ボタンで閉じられた場合は何も変更しません。
5-3. Cancel時は入力内容を破棄する処理
Cancel時は、基本的に親フォーム側で何もしないようにします。
C#using (var form = new NameInputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
labelResult.Text = form.UserName;
}
}
このように書けば、Cancel時にはifブロックに入らないため、入力内容は反映されません。
明示的にキャンセル処理を書きたい場合は、次のようにします。
C#using (var form = new NameInputForm())
{
DialogResult result = form.ShowDialog();
if (result == DialogResult.OK)
{
labelResult.Text = form.UserName;
}
else if (result == DialogResult.Cancel)
{
MessageBox.Show("入力はキャンセルされました");
}
}
ただし、実務では「OK以外は何もしない」という書き方のほうがシンプルでミスが少ないです。
5-4. 入力チェック後にDialogResult.OKを返す方法
入力チェックを行う場合は、OKボタンのDialogResultプロパティを最初からOKに設定しないほうが扱いやすいことがあります。
なぜなら、ボタンにDialogResult.OKを設定していると、クリック時に自動で閉じる動作が働くためです。
入力チェック後に閉じたい場合は、クリックイベントで手動制御します。
C#private void buttonOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください");
return;
}
this.DialogResult = DialogResult.OK;
}
Cancelボタンはそのまま設定して問題ありません。
C#buttonCancel.DialogResult = DialogResult.Cancel;
this.CancelButton = buttonCancel;
入力チェックに成功したときだけDialogResult.OKを設定すれば、不正な入力のままダイアログが閉じることを防げます。
6. MessageBox.ShowでDialogResultを使う方法
6-1. MessageBox.Showの戻り値を受け取る
MessageBox.Show()もDialogResultを返します。
たとえば、OKボタンだけのメッセージボックスは次のように表示できます。
C#DialogResult result = MessageBox.Show("処理が完了しました");
OKが押されたかを判定するなら、次のように書きます。
C#if (MessageBox.Show("処理が完了しました") == DialogResult.OK)
{
// OKが押された
}
ただし、OKボタンだけのメッセージでは、結果を判定する必要がない場合も多いです。
DialogResultが特に役立つのは、Yes/NoやOK/Cancelのように複数の選択肢がある場合です。
6-2. Yes/Noの結果で処理を分岐する
削除確認などでは、MessageBoxButtons.YesNoを使います。
C#DialogResult result = MessageBox.Show(
"本当に削除しますか?",
"確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
if (result == DialogResult.Yes)
{
// 削除する
}
else
{
// 削除しない
}
より短く書くなら、次のようにできます。
C#if (MessageBox.Show("削除しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
DeleteData();
}
重要なのは、MessageBoxButtons.YesNoを指定した場合、戻り値はDialogResult.YesまたはDialogResult.Noになるという点です。
DialogResult.OKでは判定しないように注意しましょう。
6-3. OK/Cancelの確認メッセージを作る
OK/Cancel形式の確認メッセージを表示する場合は、MessageBoxButtons.OKCancelを使います。
C#DialogResult result = MessageBox.Show(
"処理を実行しますか?",
"確認",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Information
);
if (result == DialogResult.OK)
{
// OK時の処理
}
else if (result == DialogResult.Cancel)
{
// Cancel時の処理
}
実行確認ではOK/Cancel、意思確認ではYes/Noを使うと自然です。
たとえば、「この処理を開始しますか?」ならOK/Cancelでもよいですが、「保存しますか?」ならYes/Noのほうが意味が分かりやすい場合があります。
6-4. MessageBoxButtonsとDialogResultの対応関係
MessageBoxButtonsで指定したボタンに応じて、返ってくるDialogResultが変わります。
代表的な対応は次のとおりです。
C#MessageBoxButtons.OK
// DialogResult.OK
MessageBoxButtons.OKCancel
// DialogResult.OK または DialogResult.Cancel
MessageBoxButtons.YesNo
// DialogResult.Yes または DialogResult.No
MessageBoxButtons.YesNoCancel
// DialogResult.Yes、DialogResult.No、DialogResult.Cancel
MessageBoxButtons.RetryCancel
// DialogResult.Retry または DialogResult.Cancel
MessageBoxButtons.AbortRetryIgnore
// DialogResult.Abort、DialogResult.Retry、DialogResult.Ignore
たとえば、Yes/Noのメッセージに対してDialogResult.OKを判定しても、期待どおりには動きません。
C#// 誤り
if (MessageBox.Show("保存しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.OK)
{
Save();
}
正しくは、DialogResult.Yesを判定します。
C#// 正しい
if (MessageBox.Show("保存しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
Save();
}
7. DialogResultがうまく動かないときの原因と対処法
7-1. ShowではなくShowDialogを使っているか確認する
DialogResultを戻り値として受け取りたい場合は、ShowDialog()を使う必要があります。
次のようにShow()で表示している場合、ShowDialog()のように結果を受け取ることはできません。
C#var form = new InputForm();
form.Show();
Show()はモードレス表示です。
フォームを表示したあとも親フォーム側の処理は止まりません。
一方、ShowDialog()はモーダル表示です。
フォームが閉じられるまで親フォーム側の処理が待機し、閉じたあとにDialogResultを返します。
C#using (var form = new InputForm())
{
DialogResult result = form.ShowDialog();
}
OK/Cancelの結果を使いたい場合は、まずShowDialog()で表示しているか確認しましょう。
7-2. ボタンのDialogResultプロパティが未設定
OKボタンを押してもDialogResult.OKにならない場合、ボタンのDialogResultプロパティが未設定の可能性があります。
C#buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
デザイナーで作成したボタンは、初期状態ではDialogResultがNoneになっていることがあります。
その場合、ボタンをクリックしてもフォームの結果がOKやCancelになりません。
プロパティウィンドウで、OKボタンにはOK、CancelボタンにはCancelを設定しましょう。
また、コードで明示的に設定しても問題ありません。
C#public InputForm()
{
InitializeComponent();
buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
}
7-3. DialogResultを設定してもフォームが閉じないケース
通常、ShowDialog()で表示したフォームに対してDialogResult.OKなどを設定するとフォームは閉じます。
しかし、次のようなケースでは閉じないことがあります。
C#private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
FormClosingイベントでe.Cancel = trueを設定していると、フォームを閉じる処理がキャンセルされます。
そのため、DialogResultを設定しても画面が閉じないように見えることがあります。
また、入力チェックのために閉じる処理を止めている場合もあります。
C#private void InputForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult == DialogResult.OK && string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください");
e.Cancel = true;
}
}
このような制御をしている場合は、FormClosingイベントの中身を確認しましょう。
7-4. FormClosingイベントで閉じる処理をキャンセルしている場合
FormClosingイベントは、フォームが閉じられる直前に発生します。
ここでe.Cancel = trueを指定すると、フォームは閉じません。
C#private void InputForm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
このコードがあると、OKボタンを押してもCancelボタンを押しても、×ボタンを押してもフォームは閉じなくなります。
入力チェックで使う場合は、条件を限定する必要があります。
C#private void InputForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.DialogResult == DialogResult.OK &&
string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください");
e.Cancel = true;
}
}
このようにすれば、OK時だけ入力チェックを行い、Cancel時はそのまま閉じられます。
7-5. モーダル表示とモードレス表示の違いによる勘違い
ShowDialog()はモーダル表示、Show()はモードレス表示です。
モーダル表示では、ダイアログが閉じるまで親フォームの操作や処理が待機されます。
C#DialogResult result = form.ShowDialog();
モードレス表示では、フォームを表示したあとも親フォーム側の処理が続きます。
C#form.Show();
DialogResultの戻り値を使った判定は、基本的にShowDialog()で行います。
Show()で表示したフォームに対して、次のような書き方はできません。
C#// Show()はDialogResultを返さない
form.Show();
結果を待ってから処理したいならShowDialog()、別ウィンドウとして開いたまま親フォームも操作したいならShow()を使います。
8. DialogResultを使うときの注意点
8-1. 親フォーム側で判定処理を書くのが基本
DialogResultを使うときは、親フォーム側で結果を判定するのが基本です。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// 親フォーム側で処理する
labelName.Text = form.UserName;
}
}
子フォーム側では、入力値を保持したり、OK/Cancelの結果を設定したりします。
親フォーム側では、OKだった場合だけ値を取得して反映します。
この役割分担にすると、コードが分かりやすくなります。
子フォーム側で親フォームのコントロールを直接操作するよりも、プロパティを通して値を渡すほうが保守しやすいです。
8-2. DialogResultと入力値の取得タイミング
入力値は、ShowDialog()が閉じたあと、フォームが破棄される前に取得します。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string value = form.InputText;
}
}
usingブロックの中であれば、フォームのプロパティにアクセスできます。
しかし、usingブロックを抜けるとDispose()されるため、フォームのコントロールへアクセスすべきではありません。
よい例です。
C#string value;
using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
value = form.InputText;
}
}
避けたい例です。
C#InputForm form;
using (form = new InputForm())
{
form.ShowDialog();
}
// Dispose後にアクセスするのは避ける
string value = form.InputText;
入力値は、ShowDialog()の結果を確認した直後に取得しましょう。
8-3. フォームの破棄とDisposeの考え方
ShowDialog()で表示したフォームは、使い終わったら破棄するのが基本です。
そのため、次のようにusingを使うのが安全です。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string value = form.InputText;
}
}
usingを使うと、自動でDispose()が呼び出されます。
フォームには、コントロールやウィンドウハンドルなどのリソースが含まれるため、使い終わったら解放することが大切です。
特に、設定画面や検索画面などを何度も開くアプリでは、フォームの破棄を忘れないようにしましょう。
8-4. WPFではDialogResultの扱いが異なる点に注意
この記事で解説しているDialogResultは、主にWindowsフォームの話です。
WPFにもShowDialog()やDialogResultに近い仕組みがありますが、扱いは異なります。
Windowsフォームでは、DialogResult.OKやDialogResult.Cancelのような列挙値を使います。
一方、WPFのWindow.DialogResultは、bool?型です。
C#this.DialogResult = true; // OK相当
this.DialogResult = false; // Cancel相当
WPFでは、親ウィンドウ側で次のように判定します。
C#bool? result = dialog.ShowDialog();
if (result == true)
{
// OK相当
}
WindowsフォームとWPFでは書き方が違うため、検索して見つけたコードをそのまま混ぜないように注意しましょう。
9. C# DialogResultのよくある質問
9-1. DialogResult.Noneとは何か?
DialogResult.Noneは、ダイアログの結果がまだ設定されていない状態を表します。
ボタンのDialogResultプロパティがNoneのままだと、そのボタンを押してもOKやCancelとして扱われません。
C#buttonOK.DialogResult = DialogResult.None;
通常、OKボタンにはDialogResult.OK、CancelボタンにはDialogResult.Cancelを設定します。
C#buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
Noneは「まだ結果がない」「結果として扱わない」という意味で理解すると分かりやすいです。
9-2. ×ボタンで閉じた場合は何が返る?
×ボタンで閉じた場合、OKボタンが押されたわけではありません。
そのため、親フォーム側ではOK以外をキャンセル扱いにするのが安全です。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// OK時のみ処理
}
else
{
// Cancelまたは×ボタン
}
}
×ボタンを押した場合の細かい戻り値に依存するより、DialogResult.OKかどうかで判定するほうが実務では分かりやすいです。
C#if (form.ShowDialog() != DialogResult.OK)
{
return;
}
この書き方なら、OK以外の終了方法をすべて中断扱いにできます。
9-3. Cancelボタンを押してもCancelにならない原因は?
Cancelボタンを押してもDialogResult.Cancelにならない場合は、ボタンのDialogResultプロパティが設定されていない可能性があります。
C#buttonCancel.DialogResult = DialogResult.Cancel;
また、EscキーでCancelを実行したい場合は、フォームのCancelButtonプロパティも設定します。
C#this.CancelButton = buttonCancel;
設定例です。
C#public InputForm()
{
InitializeComponent();
buttonCancel.DialogResult = DialogResult.Cancel;
this.CancelButton = buttonCancel;
}
これで、Cancelボタンのクリックだけでなく、EscキーでもCancel操作を実行できます。
9-4. OKボタンを押しても閉じないようにできる?
できます。
入力チェックに失敗した場合など、OKボタンを押しても閉じたくないことがあります。
その場合は、最初からボタンのDialogResultプロパティをOKに設定せず、クリックイベントで入力チェック後にDialogResult.OKを設定します。
C#private void buttonOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください");
return;
}
this.DialogResult = DialogResult.OK;
}
このコードでは、名前が空の場合はreturnするため、フォームは閉じません。
入力チェックに成功した場合だけDialogResult.OKを設定し、ダイアログを閉じます。
9-5. DialogResultは自作フォームでも使える?
使えます。
むしろ、DialogResultは自作の入力フォームや設定フォームでよく使われます。
子フォーム側では、OKボタンとCancelボタンにDialogResultを設定します。
C#buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
親フォーム側では、ShowDialog()の戻り値を判定します。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
string value = form.InputText;
MessageBox.Show(value);
}
}
このように、自作フォームでもDialogResultを使うことで、OK時だけ処理する、Cancel時は破棄する、といった自然なダイアログ処理を実装できます。
まとめ
C#のDialogResultは、ダイアログでユーザーがどの操作をしたかを判定するための仕組みです。
ShowDialog()でフォームを表示すると、フォームが閉じられたあとにDialogResultが戻り値として返ります。
基本的な使い方は次のとおりです。
C#using (var form = new InputForm())
{
if (form.ShowDialog() == DialogResult.OK)
{
// OK時だけ処理する
}
}
OKボタンやCancelボタンには、DialogResultプロパティを設定します。
C#buttonOK.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
EnterキーやEscキーに対応したい場合は、AcceptButtonとCancelButtonも設定します。
C#this.AcceptButton = buttonOK;
this.CancelButton = buttonCancel;
また、MessageBox.Show()でもDialogResultを使って、Yes/NoやOK/Cancelの結果を判定できます。
C#if (MessageBox.Show("削除しますか?", "確認", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
// 削除する
}
DialogResultがうまく動かない場合は、Show()ではなくShowDialog()を使っているか、ボタンのDialogResultプロパティが設定されているか、FormClosingイベントで閉じる処理をキャンセルしていないかを確認しましょう。
C#で入力フォームや確認ダイアログを作るなら、DialogResultは必ず押さえておきたい基本機能です。
OK時だけ処理する、Cancel時は破棄する、Yes/Noで分岐する、といった定番処理を整理して書けるようになります。

