C# Windows Forms入門|フォーム作成から画面遷移・データ受け渡しまで初心者向けに解説

はじめに

C#でデスクトップアプリを作りたい初心者にとって、最初に学びやすい選択肢のひとつがWindows Formsです。検索キーワードとして「csharp form」と調べている人の多くは、C#でフォーム画面を作る方法、ボタンやテキストボックスの使い方、複数画面の切り替え、フォーム間でのデータ受け渡しを知りたいのではないでしょうか。

Windows Formsは、Visual Studioのデザイナーを使って画面を作成できるため、プログラミング初心者でも画面の見た目を確認しながら学習できます。この記事では、C# Windows Formsの基礎から、フォーム作成、イベント処理、画面遷移、データ受け渡し、よくあるエラー対策までを初心者向けに解説します。

1. C# Windows Formsとは?初心者が最初に知るべき基礎

1-1. Windows Formsでできること

Windows Formsは、C#でWindows向けのデスクトップアプリを作成するためのGUIフレームワークです。GUIとは、ボタン、入力欄、ラベル、一覧表などを使って操作できる画面のことです。

Windows Formsを使うと、次のようなアプリを作成できます。

顧客情報を入力するアプリ、売上データを表示するアプリ、ファイルを選択して処理するツール、社内業務用の管理画面、簡単な電卓アプリ、設定画面付きのデスクトップツールなどです。

特にWindows Formsは、画面部品をドラッグ&ドロップで配置できるため、「C#で画面を作る感覚」を理解しやすいのが特徴です。

1-2. WPF・コンソールアプリ・Webアプリとの違い

C#にはWindows Forms以外にも、WPF、コンソールアプリ、ASP.NETなどのWebアプリ開発があります。

コンソールアプリは、黒い画面に文字を表示して操作するアプリです。C#の文法学習には向いていますが、ボタンや入力フォームのある画面は作れません。

WPFは、Windows Formsよりも新しいデスクトップアプリ開発技術です。デザインの自由度が高く、データバインディングなど高度な仕組みも使えます。ただし、XAMLという画面定義の知識が必要になるため、初心者には少し難しく感じる場合があります。

Webアプリは、ブラウザ上で動くアプリです。HTML、CSS、JavaScript、サーバーサイドの知識も必要になります。

一方、Windows FormsはC#のコードとVisual Studioのフォームデザイナーを中心に学べるため、初心者が「画面のあるアプリ」を作る最初のステップとして適しています。

1-3. 「csharp form」で検索する人が知りたいこと

「csharp form」と検索する人は、主に次のような情報を探していることが多いです。

C#でフォームを作る方法、Windows Formsプロジェクトの作成方法、Formクラスの使い方、ボタンクリック時の処理、TextBoxの値を取得する方法、別フォームを開く方法、フォーム間で値を渡す方法、ShowとShowDialogの違い、フォームを閉じるとアプリが終了する理由などです。

この記事では、これらの疑問を順番に解消できるように、基礎から実践例までをつなげて解説していきます。

1-4. Windows Forms学習に必要なC#の前提知識

Windows Formsを学ぶ前に、最低限理解しておきたいC#の知識があります。

変数、if文、メソッド、クラス、プロパティ、コンストラクタ、イベント、アクセス修飾子、例外処理などです。

すべてを完璧に理解してから始める必要はありません。Windows Formsを作りながら、Button、Label、TextBoxなどの部品を操作する中で、自然にC#のクラスやイベントの考え方が身についていきます。

2. C# Windows Forms開発環境を準備する

2-1. Visual Studioのインストール

C# Windows Formsを開発するには、Visual Studioを使うのが一般的です。Visual Studioには無料で使えるCommunity版があります。

インストール時には、ワークロードとして「.NET デスクトップ開発」を選択します。これを選ばないと、Windows Formsアプリのテンプレートが表示されない場合があります。

インストール後、Visual Studioを起動して新しいプロジェクトを作成できる状態にします。

2-2. Windowsフォームアプリのプロジェクト作成手順

Visual StudioでWindows Formsアプリを作る基本手順は次のとおりです。

まず、Visual Studioを起動し、「新しいプロジェクトの作成」を選択します。検索欄に「Windows Forms」と入力し、「Windows フォーム アプリ」を選びます。

プロジェクト名を入力し、保存場所を指定します。フレームワークを選択して作成すると、Form1という最初のフォームが表示されます。

このForm1が、アプリを起動したときに最初に表示される画面になります。

2-3. .NETと.NET Frameworkの違い

Windows Formsには、.NET版と.NET Framework版があります。

.NET Frameworkは、昔から使われてきたWindows向けのフレームワークです。古い業務アプリや既存システムでは、今でも.NET FrameworkのWindows Formsが使われていることがあります。

一方、.NETは新しい開発環境で、現在のC#開発ではこちらが主流です。新しく学習する場合は、特別な理由がなければ.NET版のWindowsフォームアプリを選ぶとよいでしょう。

ただし、会社や学習教材によっては.NET Frameworkを前提にしている場合もあります。既存のプロジェクトに合わせる必要がある場合は、その環境に従いましょう。

2-4. フォームデザイナーが表示されないときの対処法

Windows Formsを学習していると、フォームデザイナーが表示されないことがあります。

よくある原因は、必要なワークロードがインストールされていない、プロジェクトテンプレートの選択を間違えている、Form1.csではなく別のファイルを開いている、コードにエラーがある、Designer.csを直接編集して壊してしまった、などです。

フォームデザイナーを表示したい場合は、ソリューションエクスプローラーでForm1.csを右クリックし、「デザイナーの表示」を選択します。

それでも表示されない場合は、Visual Studio Installerを開き、「.NET デスクトップ開発」が入っているか確認しましょう。

3. はじめてのフォーム作成

3-1. Formクラスの基本構造

Windows Formsの画面は、Formクラスを継承したクラスとして作られます。

たとえば、最初に作成されるForm1は次のような構造です。

C#
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}

Form1 : Formは、Form1クラスがFormクラスを継承していることを表します。

InitializeComponent()は、フォーム上に配置したボタンやラベルなどを初期化するためのメソッドです。通常、このメソッドは自動生成されるため、自分で中身を編集する必要はありません。

3-2. フォームの名前・タイトル・サイズを設定する

フォームには、名前、タイトル、サイズなどの設定があります。

フォームのタイトルは、プロパティウィンドウのTextで設定できます。たとえば、Textを「入力フォーム」にすると、ウィンドウ上部のタイトルバーに「入力フォーム」と表示されます。

フォームのサイズはSizeプロパティで設定できます。コードで設定する場合は次のように書きます。

C#
this.Text = "入力フォーム";
this.Width = 500;
this.Height = 300;

フォームの名前はNameプロパティで管理されます。コード上で扱う識別名なので、わかりやすい名前にしておくと開発しやすくなります。

3-3. Button・Label・TextBoxを配置する

Windows Formsでは、ツールボックスからコントロールをドラッグ&ドロップしてフォーム上に配置できます。

まず、Labelを配置して「名前を入力してください」と表示します。次にTextBoxを配置して、ユーザーが文字を入力できるようにします。最後にButtonを配置して、「表示」や「送信」などの文字を設定します。

それぞれのコントロールには、Nameプロパティを設定しておくとコードから扱いやすくなります。

たとえば、次のような名前にします。

LabelはlabelMessage、TextBoxはtextBoxName、ButtonはbuttonShowのようにします。

3-4. プロパティウィンドウの使い方

プロパティウィンドウは、フォームやコントロールの設定を変更するための画面です。

Text、Name、Size、Location、Font、BackColor、Enabled、Visibleなどを設定できます。

初心者が特によく使うのは、NameTextです。

Nameはコードで使う名前、Textは画面に表示される文字です。たとえば、ButtonのNamebuttonLoginTextを「ログイン」にすると、コードではbuttonLoginとして扱い、画面には「ログイン」と表示されます。

3-5. フォームを実行して画面表示を確認する

フォームを作成したら、Visual Studio上部の開始ボタンを押して実行します。ショートカットキーではF5でデバッグ実行できます。

正しく作成できていれば、作成したフォームがWindowsアプリとして起動します。

実行して画面の見た目を確認しながら、ボタンや入力欄の位置、文字の大きさ、フォームサイズを調整していきましょう。

4. イベント処理の基本を理解する

4-1. クリックイベントとは

Windows Formsでは、ユーザーの操作に応じて処理を実行します。この仕組みをイベントと呼びます。

たとえば、ボタンをクリックしたときに処理を実行するのがクリックイベントです。

Buttonをダブルクリックすると、Visual Studioが自動でクリックイベントのメソッドを作成してくれます。

C#
private void buttonShow_Click(object sender, EventArgs e)
{
}

この中に処理を書くことで、ボタンがクリックされたときの動作を作れます。

4-2. ButtonクリックでLabelの文字を変更する

ButtonをクリックしたときにLabelの文字を変更する例です。

C#
private void buttonShow_Click(object sender, EventArgs e)
{
labelMessage.Text = "ボタンがクリックされました";
}

labelMessage.Textに文字列を代入すると、画面上のLabelに表示される文字が変わります。

Windows Formsでは、このようにコントロールのプロパティを書き換えることで、画面表示を変更します。

4-3. TextBoxに入力された値を取得する

TextBoxに入力された値は、Textプロパティから取得できます。

C#
private void buttonShow_Click(object sender, EventArgs e)
{
string name = textBoxName.Text;
labelMessage.Text = "こんにちは、" + name + "さん";
}

ユーザーがTextBoxに「田中」と入力してボタンを押すと、Labelに「こんにちは、田中さん」と表示されます。

文字列補間を使うと、次のようにも書けます。

C#
labelMessage.Text = $"こんにちは、{name}さん";

4-4. よく使うイベント一覧

Windows Formsでよく使うイベントには、次のようなものがあります。

Clickはクリックされたとき、TextChangedはTextBoxの文字が変わったとき、Loadはフォームが表示される前後の初期化処理、FormClosingはフォームを閉じる直前、SelectedIndexChangedはComboBoxやListBoxの選択が変わったときに使います。

たとえば、フォーム起動時に初期値を設定したい場合は、FormのLoadイベントを使います。

C#
private void Form1_Load(object sender, EventArgs e)
{
labelMessage.Text = "名前を入力してください";
}

4-5. イベントが動かないときの確認ポイント

イベントが動かない場合は、イベントメソッドがコントロールに関連付けられているか確認しましょう。

ボタンをダブルクリックして作成したメソッドであれば通常は自動で関連付けられます。しかし、メソッド名を変更したり、コードをコピーしたりした場合、イベントとの接続が切れていることがあります。

プロパティウィンドウの稲妻マークを開き、Clickイベントに正しいメソッド名が設定されているか確認します。

また、コントロールのEnabledfalseになっていないか、別のコントロールに隠れていないかも確認しましょう。

5. 複数フォームを作成する方法

5-1. 新しいフォームを追加する手順

複数画面のアプリを作る場合は、新しいフォームを追加します。

ソリューションエクスプローラーでプロジェクトを右クリックし、「追加」から「Windows フォーム」を選択します。名前をForm2.csなどにして追加すると、新しいフォームが作成されます。

Form1をメイン画面、Form2を詳細画面や入力画面として使うように役割を分けるとわかりやすくなります。

5-2. Form1とForm2の役割を整理する

複数フォームを扱うときは、それぞれの役割を明確にすることが大切です。

Form1はメニュー画面、Form2は入力画面、Form3は確認画面のように分けると、コードの見通しがよくなります。

初心者のうちは、すべての処理をForm1に詰め込みがちですが、画面ごとに責任を分けることで、後から修正しやすくなります。

5-3. 別フォームを開く基本コード

Form1からForm2を開くには、Form2のインスタンスを作成してShow()を呼び出します。

C#
private void buttonOpen_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
}

これで、ボタンをクリックするとForm2が表示されます。

5-4. ShowとShowDialogの違い

別フォームを開く方法には、Show()ShowDialog()があります。

Show()は通常の表示です。Form2を開いたあとも、Form1を操作できます。

C#
Form2 form2 = new Form2();
form2.Show();

ShowDialog()はモーダル表示です。Form2を閉じるまで、Form1を操作できません。

C#
Form2 form2 = new Form2();
form2.ShowDialog();

設定画面や確認画面のように、ユーザーの入力が終わるまで元の画面を操作させたくない場合はShowDialog()を使います。

5-5. モーダル画面と通常画面の使い分け

通常画面は、複数の画面を同時に操作したい場合に向いています。たとえば、一覧画面を開いたまま詳細画面を表示するようなケースです。

モーダル画面は、入力や確認を完了するまで次に進ませたくない場合に向いています。たとえば、ログイン画面、設定画面、確認ダイアログ、ファイル選択画面などです。

画面遷移を設計するときは、「元の画面を操作できてもよいか」を基準に考えると判断しやすくなります。

6. C# Windows Formsで画面遷移を実装する

6-1. ボタンクリックで別フォームへ遷移する

C# Windows Formsで画面遷移を実装する基本は、ボタンクリックイベントで別フォームを開くことです。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
}

このコードでは、Form1を表示したままForm2を開きます。

6-2. 現在のフォームを閉じて次のフォームを表示する

現在のフォームを閉じて次のフォームを表示したい場合は、次のように書きたくなります。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
this.Close();
}

ただし、Form1がApplication.Run(new Form1())で起動されたメインフォームの場合、Form1を閉じるとアプリ全体が終了することがあります。

そのため、メインフォームを閉じる画面遷移では注意が必要です。

6-3. Hideを使ってフォームを非表示にする

アプリを終了させずに現在のフォームを隠したい場合は、Hide()を使います。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
this.Hide();
}

この方法ではForm1は閉じられず、非表示になります。

ただし、非表示にしたフォームが残り続けるため、不要になったタイミングで閉じる設計も必要です。

6-4. CloseとDisposeの違い

Close()はフォームを閉じるためのメソッドです。フォームを閉じると、通常はリソースも解放されます。

Dispose()は、フォームやコントロールが使用しているリソースを明示的に解放するためのメソッドです。

通常のWindows Forms開発では、フォームを閉じるときはClose()を使えば十分です。Dispose()は、フォームを明示的に破棄したい場合や、usingを使ってダイアログを扱う場合などに使います。

C#
using (Form2 form2 = new Form2())
{
form2.ShowDialog();
}

6-5. 複数画面を扱うときの注意点

複数画面を扱うときは、フォームを必要以上に何度も作らないように注意しましょう。

ボタンを押すたびに新しいフォームを作ると、同じ画面が何枚も開いてしまうことがあります。

また、Form1からForm2、Form2からForm3、Form3からForm1のように複雑に参照し合うと、コードがわかりにくくなります。

画面遷移が増えてきたら、どのフォームがどのフォームを開くのか、データはどこで管理するのかを整理しましょう。

7. フォーム間でデータを受け渡しする方法

7-1. コンストラクタで値を渡す方法

フォーム間でデータを渡す基本的な方法のひとつが、コンストラクタを使う方法です。

Form2側に、値を受け取るコンストラクタを作成します。

C#
public partial class Form2 : Form
{
public Form2(string name)
{
InitializeComponent();
labelName.Text = name;
}
}

Form1からForm2を開くときに値を渡します。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
string name = textBoxName.Text;
Form2 form2 = new Form2(name);
form2.Show();
}

この方法は、フォームを開く時点で必要な値を渡したい場合に向いています。

7-2. プロパティを使って値を渡す方法

プロパティを使って値を渡すこともできます。

Form2にpublicプロパティを用意します。

C#
public partial class Form2 : Form
{
public string UserName { get; set; }

private void Form2_Load(object sender, EventArgs e)
{
labelName.Text = UserName;
}
}

Form1からForm2を開く前にプロパティへ値を設定します。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.UserName = textBoxName.Text;
form2.Show();
}

プロパティを使う方法は、複数の値をあとから設定したい場合に便利です。

7-3. ShowDialogの戻り値で入力結果を受け取る方法

Form2で入力した結果をForm1に戻したい場合は、ShowDialog()DialogResultを使う方法があります。

Form2側でOKボタンがクリックされたら、結果を設定して閉じます。

C#
public string InputName { get; private set; }

private void buttonOk_Click(object sender, EventArgs e)
{
InputName = textBoxName.Text;
this.DialogResult = DialogResult.OK;
this.Close();
}

Form1側では、Form2をモーダル表示して結果を受け取ります。

C#
private void buttonOpen_Click(object sender, EventArgs e)
{
using (Form2 form2 = new Form2())
{
if (form2.ShowDialog() == DialogResult.OK)
{
labelResult.Text = form2.InputName;
}
}
}

入力ダイアログや設定画面では、この方法がよく使われます。

7-4. publicプロパティでTextBoxの値を取得する方法

Form2のTextBoxの値を外部から直接取得するのではなく、publicプロパティを通して取得するのが基本です。

C#
public string UserName
{
get { return textBoxName.Text; }
}

Form1側では次のように取得します。

C#
using (Form2 form2 = new Form2())
{
if (form2.ShowDialog() == DialogResult.OK)
{
string name = form2.UserName;
labelResult.Text = name;
}
}

TextBox自体をpublicにして直接アクセスする方法もありますが、フォーム内部の部品に依存しすぎるためおすすめしません。

7-5. イベントを使ってフォーム間で値を通知する方法

フォーム間の依存を減らしたい場合は、イベントを使って値を通知する方法もあります。

Form2でイベントを定義します。

C#
public event Action<string> NameSubmitted;

private void buttonSubmit_Click(object sender, EventArgs e)
{
NameSubmitted?.Invoke(textBoxName.Text);
}

Form1側でイベントを購読します。

C#
private void buttonOpen_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();

form2.NameSubmitted += name =>
{
labelResult.Text = name;
};

form2.Show();
}

この方法では、Form2はForm1の存在を知る必要がありません。画面同士の結びつきを弱くできるため、少し大きなアプリでは有効です。

7-6. グローバル変数・staticを使う場合の注意点

初心者がやりがちな方法として、static変数を使ってフォーム間でデータを共有する方法があります。

C#
public static string UserName;

小さなサンプルでは動きますが、どこからでも値を書き換えられるため、アプリが大きくなると原因不明のバグにつながりやすくなります。

staticを使う場合は、アプリ全体で本当に共有すべき設定値なのかを考えましょう。単にForm1からForm2へ値を渡したいだけなら、コンストラクタやプロパティを使う方が安全です。

8. 入力フォームを作る実践例

8-1. 名前入力フォームの完成イメージ

ここでは、Form1で名前を入力し、Form2で入力結果を表示する簡単なアプリを作ります。

Form1には、Label、TextBox、Buttonを配置します。TextBoxに名前を入力し、ButtonをクリックするとForm2が開きます。Form2には、受け取った名前を表示するLabelを配置します。

この例を通して、入力値の取得、入力チェック、画面遷移、データ受け渡しをまとめて確認できます。

8-2. 入力値を取得して別画面に表示する

Form2にコンストラクタを作成します。

C#
public partial class Form2 : Form
{
public Form2(string name)
{
InitializeComponent();
labelResult.Text = $"こんにちは、{name}さん";
}
}

Form1のボタンクリックイベントで、TextBoxの値を取得してForm2へ渡します。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
string name = textBoxName.Text;

Form2 form2 = new Form2(name);
form2.Show();
}

これで、Form1に入力した値をForm2に表示できます。

8-3. 入力チェックを追加する

実際のアプリでは、入力欄が空のまま次の画面に進めないようにする必要があります。

C#
private void buttonNext_Click(object sender, EventArgs e)
{
string name = textBoxName.Text;

if (string.IsNullOrWhiteSpace(name))
{
MessageBox.Show("名前を入力してください。");
return;
}

Form2 form2 = new Form2(name);
form2.Show();
}

string.IsNullOrWhiteSpace()を使うと、空文字だけでなく、スペースだけの入力もチェックできます。

8-4. 空欄・数値・文字数チェックの実装

入力チェックには、さまざまな種類があります。

空欄チェックは次のように書きます。

C#
if (string.IsNullOrWhiteSpace(textBoxName.Text))
{
MessageBox.Show("名前を入力してください。");
return;
}

数値チェックにはint.TryParse()を使います。

C#
if (!int.TryParse(textBoxAge.Text, out int age))
{
MessageBox.Show("年齢は数値で入力してください。");
return;
}

文字数チェックはLengthを使います。

C#
if (textBoxName.Text.Length > 20)
{
MessageBox.Show("名前は20文字以内で入力してください。");
return;
}

入力フォームでは、ユーザーが間違った値を入力する前提でチェックを入れることが大切です。

8-5. MessageBoxでエラーや確認を表示する

Windows Formsでは、MessageBox.Show()を使うと簡単にメッセージを表示できます。

C#
MessageBox.Show("登録しました。");

確認ダイアログを表示することもできます。

C#
DialogResult result = MessageBox.Show(
"登録してもよろしいですか?",
"確認",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);

if (result == DialogResult.Yes)
{
MessageBox.Show("登録しました。");
}

エラー、確認、完了通知など、ユーザーに状態を伝える場面でMessageBoxはよく使われます。

9. Windows Formsでよく使うコントロール

9-1. Label・TextBox・Button

Labelは文字を表示するためのコントロールです。説明文や結果表示に使います。

TextBoxは文字を入力するためのコントロールです。名前、住所、検索キーワードなどを入力する場面で使います。

Buttonはクリック操作を受け付けるためのコントロールです。登録、検索、削除、次へ、戻るなどの操作に使います。

Windows Formsの基本は、この3つのコントロールから始まります。

9-2. CheckBox・RadioButton

CheckBoxは、複数の項目を選択できるコントロールです。

C#
if (checkBoxAgree.Checked)
{
MessageBox.Show("同意済みです。");
}

RadioButtonは、複数の選択肢の中からひとつだけ選ばせたい場合に使います。

性別、支払い方法、表示形式など、排他的な選択に向いています。

9-3. ComboBox・ListBox

ComboBoxは、ドロップダウン形式で項目を選択するコントロールです。

C#
comboBoxPrefecture.Items.Add("東京");
comboBoxPrefecture.Items.Add("大阪");
comboBoxPrefecture.Items.Add("福岡");

選択された値は次のように取得できます。

C#
string selected = comboBoxPrefecture.Text;

ListBoxは、一覧から項目を選択するためのコントロールです。複数の候補を画面に表示したい場合に便利です。

9-4. DataGridView

DataGridViewは、表形式のデータを表示・編集するためのコントロールです。

顧客一覧、商品一覧、売上一覧など、業務アプリではよく使われます。

C#
dataGridView1.Rows.Add("田中", 30);
dataGridView1.Rows.Add("佐藤", 25);

データベースと組み合わせることで、本格的な一覧画面を作ることもできます。

9-5. Panel・GroupBox

Panelは、複数のコントロールをまとめるためのコンテナです。画面の一部を区切ったり、スクロール可能な領域を作ったりできます。

GroupBoxは、関連する項目を枠で囲んでまとめるために使います。たとえば、性別のRadioButtonをまとめたり、検索条件をまとめたりする場合に便利です。

画面が複雑になってきたら、PanelやGroupBoxを使って整理しましょう。

9-6. コントロールの配置を整えるコツ

Windows Formsでは、コントロールの配置を整えることで見やすい画面になります。

LabelとTextBoxの位置をそろえる、Buttonのサイズを統一する、余白を一定にする、関連する項目をGroupBoxでまとめる、TabIndexを設定してキーボード操作しやすくする、といった工夫が大切です。

また、フォームサイズを変更したときにレイアウトが崩れないように、AnchorやDockプロパティも活用しましょう。

10. Windows Forms初心者がつまずきやすいエラーと対処法

10-1. フォームが二重に開いてしまう

ボタンを押すたびに次のコードを実行すると、Form2が何枚も開いてしまいます。

C#
Form2 form2 = new Form2();
form2.Show();

一度だけ開きたい場合は、既に開いているフォームを管理する必要があります。

C#
private Form2 form2;

private void buttonOpen_Click(object sender, EventArgs e)
{
if (form2 == null || form2.IsDisposed)
{
form2 = new Form2();
form2.Show();
}
else
{
form2.Activate();
}
}

これで、既にForm2が開いている場合は新しく作らず、前面に表示できます。

10-2. 別フォームのTextBoxにアクセスできない

別フォームのTextBoxにアクセスしようとしてエラーになることがあります。

原因として多いのは、TextBoxのアクセス修飾子がprivateであること、フォームのインスタンスを正しく参照していないこと、別の新しいフォームを作ってしまっていることです。

ただし、TextBoxをpublicにして直接操作するより、プロパティやメソッドを通して値を渡す方が安全です。

C#
public string UserName
{
get { return textBoxName.Text; }
}

フォーム内部のコントロールを外部から直接触る設計は、なるべく避けましょう。

10-3. NullReferenceExceptionが発生する

NullReferenceExceptionは、nullのオブジェクトにアクセスしたときに発生します。

たとえば、フォームのインスタンスを作成していないのにメソッドを呼び出すと発生します。

C#
Form2 form2 = null;
form2.Show(); // エラー

正しくは、newでインスタンスを作成します。

C#
Form2 form2 = new Form2();
form2.Show();

また、TextBoxやLabelが削除されているのにコードだけ残っている場合にも発生することがあります。デザイナー上のコントロール名とコードが一致しているか確認しましょう。

10-4. Program.csとApplication.Runの関係がわからない

Windows Formsアプリでは、Program.csにアプリの開始処理があります。

C#
Application.Run(new Form1());

このコードは、Form1をメインフォームとして起動するという意味です。

メインフォームを閉じると、アプリ全体が終了します。そのため、Form1を閉じてForm2へ移動しようとすると、アプリが終了してしまうことがあります。

画面遷移を作るときは、どのフォームがメインフォームなのかを意識しましょう。

10-5. デザイナー画面とコード画面の関係がわからない

Windows Formsでは、画面の見た目はデザイナーで作成し、その内容はDesigner.csに自動生成されます。

通常、開発者が編集するのはForm1.csです。Form1.Designer.csはVisual Studioが管理するファイルなので、初心者のうちは直接編集しない方が安全です。

デザイナーでButtonを配置すると、Designer.csにButtonの生成コードが追加されます。Form1.csでは、そのButtonのクリックイベントなどを実装します。

10-6. フォームを閉じるとアプリ全体が終了してしまう

メインフォームを閉じると、Windows Formsアプリは終了します。

たとえば、Form1がメインフォームの場合、Form1でthis.Close()を呼ぶとアプリ全体が終了します。

次の画面に移動したいだけなら、Hide()を使う方法があります。

C#
Form2 form2 = new Form2();
form2.Show();
this.Hide();

ただし、非表示のフォームが残り続けるため、アプリ終了時に適切に閉じる処理も考える必要があります。

11. Windows Forms開発で押さえておきたい設計の基本

11-1. フォームに処理を書きすぎない

初心者のうちは、ボタンクリックイベントの中にすべての処理を書いてしまいがちです。

小さなサンプルなら問題ありませんが、アプリが大きくなると、フォームのコードが長くなり、修正しにくくなります。

フォームには画面表示や入力取得の処理を中心に書き、計算処理やデータ処理は別のクラスに分けると管理しやすくなります。

11-2. 画面表示とデータ処理を分ける

たとえば、合計金額を計算する処理をフォームに直接書くのではなく、別クラスに分けます。

C#
public class PriceCalculator
{
public int CalculateTotal(int price, int quantity)
{
return price * quantity;
}
}

フォーム側では、そのクラスを呼び出します。

C#
PriceCalculator calculator = new PriceCalculator();
int total = calculator.CalculateTotal(1000, 3);
labelTotal.Text = total.ToString();

このように分けると、計算処理を別の画面でも再利用できます。

11-3. クラスを使ってデータを管理する

複数の値を扱う場合は、個別の変数で管理するよりクラスを作るとわかりやすくなります。

C#
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}

フォーム間でデータを渡す場合も、文字列を何個も渡すより、Userクラスを渡す方が整理しやすくなります。

C#
User user = new User
{
Name = textBoxName.Text,
Age = int.Parse(textBoxAge.Text)
};

Form2 form2 = new Form2(user);
form2.Show();

11-4. フォーム間の依存を減らす

Form2からForm1のTextBoxを直接操作するような設計にすると、フォーム同士が強く結びついてしまいます。

依存が強いと、画面を変更したときに別の画面まで修正が必要になりやすくなります。

フォーム間で値を渡す場合は、コンストラクタ、プロパティ、イベント、専用のデータクラスなどを使い、直接コントロールを触らない設計を意識しましょう。

11-5. 小さなアプリから設計を意識する

設計というと難しく感じるかもしれませんが、最初は小さな意識で十分です。

フォームに処理を書きすぎない、コントロール名をわかりやすくする、同じ処理をメソッドにまとめる、データはクラスで管理する、フォーム間で直接コントロールを触らない、といった基本を守るだけでも、コードはかなり読みやすくなります。

Windows Formsは初心者でも始めやすい一方で、業務アプリのような実用的な開発にも使われます。小さなアプリを作る段階から設計を意識しておくと、後から大きなアプリを作るときに役立ちます。

まとめ

C# Windows Formsは、C#でWindows向けデスクトップアプリを作るための入門しやすい開発方法です。Visual Studioのフォームデザイナーを使えば、Button、Label、TextBoxなどのコントロールを配置しながら、画面のあるアプリを直感的に作成できます。

「csharp form」と検索して学び始めた人は、まずFormクラスの基本、コントロールの配置、イベント処理、TextBoxの値取得、Buttonクリック時の処理を理解しましょう。

その次に、複数フォームの作成、ShowとShowDialogの違い、画面遷移、フォーム間のデータ受け渡しを学ぶと、実用的なWindows Formsアプリを作れるようになります。

初心者がつまずきやすいポイントとして、フォームが二重に開く、別フォームのTextBoxにアクセスできない、NullReferenceExceptionが発生する、メインフォームを閉じるとアプリが終了する、といった問題があります。これらは、フォームのインスタンス、イベント、Application.Runの仕組みを理解することで解決しやすくなります。

Windows Formsの学習では、まず小さな入力フォームや確認画面を作ってみることが大切です。実際に手を動かしながら、C#の基本文法、イベント処理、画面遷移、データ管理を少しずつ身につけていきましょう。