Form 切り替えパターン、業務画面でメニューバーから別画面に飛ぶ時の定番ですが、3つほど踏みやすい罠があります。
① 親 Form を Hide vs Close で動作が変わる
子 Form を呼ぶ時に親 Form を this.Hide() するか this.Close() するかで全然違います。Hide はインスタンス生きたまま、Close は破棄。Hide で隠して子から戻ってきたら parent.Show() で復活させるパターンが業務系では多いです。Close すると入力途中のデータが消えるので注意。 Form.ShowDialog vs Form.Show で表示モードの違いも整理してます。
② 子 Form 閉じた時の親 Form 復帰タイミング
子 Form の FormClosing イベントで親 Form を Show するパターン、タイミングを間違うと「子 Form 表示中なのに親も同時に見える」状態になります。鉄則は「子 Form の FormClosed(過去形!)で親を Show」。FormClosing は「閉じる前」、FormClosed は「閉じた後」。地味な罠ですが本番でやらかします。 Formの中にFormを表示して切り替える の MDI パターンとは挙動が違います。
③ DataGridView の選択行が切り替えで失われる
親 Form の DataGridView で行選択中に別 Form に飛んで、戻ってきた時に選択がリセットされてる事故。Hide してれば残りますが、Close → 再 new だとリセット。業務系では「Hide で隠す」+「親 Form を1つだけ生成して使い回す」のセオリーが効きます。 DataGridView × DataTable で行状態の管理も参照。
❓ よくある質問
Q1. Form 切替時の値受け渡しはどうする?
A. 親 Form を Hide して子 Form を Show するパターンなら、親のフィールドに保持した値を子のコンストラクタで渡せます。逆方向は子の public プロパティを親が参照するか、デリゲート/イベントで通知。設計の全体像は FormとFormの間で値の共有・受け渡し で網羅してます。
Q2. メイン Form の復帰タイミングは?
A. 子 Form の FormClosed イベントで parentForm.Show() を呼ぶのが最も安全。 FormClosing でやると子 Form がまだ画面に残るタイミングで親が出てくる。
Q3. 子 Form のサイズ・位置を維持するには?
A. StartPosition = FormStartPosition.Manual にして、Location と Size を保存しておく。User Settings に書き込んでおけば次回起動時にも復元できます。業務画面でユーザー体験を上げる地味な工夫。
Q4. 子 Form をたくさん開くとメモリが心配です
A. 切り替えのたびに new + Close を繰り返すよりも、Hide で生かして再利用する方が結果的にメモリ効率良いことが多いです。ただし子 Form 内で大量データを保持してると逆効果なので、データ層は親 Form or 共通クラスに分離するのが定石。 DataAdapter で Fill と Update で書いた DataTable 共有パターンと組み合わせると安全。
Q5. MDI と Hide/Show 切替の違いは?
A. MDI は「親 Form の内側に子 Form を埋め込む」、Hide/Show は「親 Form を隠して別の Form を全画面表示」のイメージ。業務画面で「メニューバーから別画面に飛ぶ」なら後者、「タブで切り替える」なら前者or Panel 切替。 Form の中に Form を表示 で MDI パターンを詳しく書いてます。
コメント