.NET Fx:ShowDialog、Show の実験
定期的に実行されるタイマーイベントハンドラの中で、フォームやメッセージボックスを条件を変えて表示し、その時の挙動を確認した。
実験コードの雛形は以下のようなコード。
public class Form1 : Form { public Form1() { ... this.timer1.Tick += new System.EventHandler(this.timer1_Tick); } private void timer1_Tick(object sender, EventArgs e) { // ここに実験コードを書く } }
調査環境
- Windows11 22H2 (OS build 22621.819)
- .NET Framework 4.8.1
実験1:同一フォームを2回モーダル表示する
form2.ShowDialog(); // オーナーの指定有無による挙動の違いはなかった
一度目の ShowDialog() は問題なくフォームが表示されるが、二度目の ShowDialog() の呼び出しで System.InvalidOperation
例外が発生した。
例外メッセージは「既に表示されているフォームをモーダルダイアログボックスとして表示できません。ShowDialog を呼び出す前に、フォームの Visible プロパティを false にしてください」という内容。
例外はこの場所でスローされている。
参考
実験2:別フォームを1回ずつモーダル表示する
if (count == 0) { count++; form2.ShowDialog(); } else if (count == 1) { count++; form3.ShowDialog(); }
これは問題なく form2 も form3 も表示され、form3 は form2 の上に表示された。
以下のようにオーナーを指定した場合でも挙動に違いはなかった。
if (count == 0) { count++; form2.ShowDialog(this); } else if (count == 1) { count++; form3.ShowDialog(form2); }
実験3:同一フォームを2回モードレス表示する
form2.Show();
この結果は・・・form2 は 1つしか表示されなかった。
実装は、オーナーを指定しない場合は、Visible = true にしているだけだった。
一方で、オーナーを指定した場合はどうなるか。
form2.Show(this);
この結果は・・・二度目の Show(this) の呼び出しで、実験1(同一フォームを2回モーダル表示する)と同じ例外が発生した。
参考
実験4:別フォームを1回ずつモードレス表示する
まずは、オーナーを指定しないケース。
if (count == 0) { count++; form2.Show(); } else if (count == 1) { count++; form3.Show(); }
この結果は・・・問題なく form2、form3 がモードレス表示された。オーナーを指定していないので、Z オーダーの順番は任意に変更できる。
次に、オーナーを指定した場合はどうなるか・・・
if (count == 0) { count++; form2.Show(this); } else if (count == 1) { count++; form3.Show(form2); }
こちらも問題なく form2, form3 がモードレス表示された。オーナーを指定したことで Z オーダーの順番は form1 < form2 < form3 となった。
実験5:メッセージボックスを複数回表示する
MessageBox.Show("fired"); // オーナーの指定有無による挙動の違いはなかった
メッセージボックスが複数個表示された。
参考
まとめ
実験した範囲内で例外が発生するのは以下のケースだった。
- すでにモーダル表示されているフォームを、再度モーダル表示しようとした場合
- オーナーを指定してすでにモードレス表示されているフォームを、再度モードレス表示しようとした場合(※オーナーを指定しない場合は例外は発生しない)