みなさんこんにちは!!
ヒロポンです!!
今回はC#のwinformのテクニックで、Formから別のFormを表示して、メインフォームを切り替えるような挙動にする方法を書いていきたいと思います!
まずは適当にFormを用意する
💡 Form の値受け渡しの設計がまだ固まってない場合は FormとFormの間で値の共有・受け渡しをする! から先に読むと、今回の切り替えパターンが活きてきます。
まずはこんな感じで適当に三つほどFormを用意します



各Formで別Formを表示するときのコード
private void button1_Click(object sender, EventArgs e)
{
var form = new Form2();
this.Hide();
if (form.ShowDialog() == DialogResult.Cancel)
{
this.Show();
}
}
private void button2_Click(object sender, EventArgs e)
{
var form = new Form3();
this.Hide();
if (form.ShowDialog() == DialogResult.Cancel)
{
this.Show();
}
}
ボタンを押して別Formを表示した時のコードをこんな感じにします。
これは別Formのインスタンスを作ったと同時に、自身を隠す。
そして別フォームを一旦表示し、閉じられた際にDialogResule.Cancelが返るので、その値を受け取ったら自身を表示すると書いています。
Form2とForm3のコードはこんな感じ
namespace FormToForm
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var form = new Form3();
this.Hide();
if (form.ShowDialog() == DialogResult.Cancel)
{
this.Show();
}
}
}
}
namespace FormToForm
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var form = new Form2();
this.Hide();
if (form.ShowDialog() == DialogResult.Cancel)
{
this.Show();
}
}
}
}
実行するとこんな感じ!
これを実行すると下記のような感じになります。
Form1が表示されている状態でbutton1を押すと

こんな感じで、別のフォームが表示されたら、自身は閉じてから開くって感じの挙動になります。
今回のコードはgithubに置いています!
今回のコードはgithubにFormToFormという名前で置いています!
ローカルにクローンつくって是非試してみてください!
💡 補足: 業務系の現場でよくハマるパターン
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 パターンを詳しく書いてます。
📚 関連記事





執筆者
バイブス父さん — 業務 SE 7 年 (正社員 2 / フリーランス 5)。 現職は SEO 直轄部の AI アドバイザー兼 PL、 副業で中小 SIer の CTO。 SES 複数社・フリーランスエージェント複数経由の経験ベースで「業務 SE 視点」 の技術 + キャリア記事を書いています。
🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る




