【WinForm】イベントを使ったフォーム間通信
複数のフォームを使ったアプリで、サブ画面の更新をきっかけにメインの画面(クラス)で登録されているメソッドが実行される方法についてみていきましょう
サンプルの構成(データを渡さなくても良い場合)
このサンプルコードは、Windows Forms アプリケーションで使用されるイベント駆動型プログラミングの一例を示しています。具体的には、メインフォーム (Form1) とサブフォーム (SubForm) 間でのイベント通信の実装方法を示しています。以下、デザイン画面とコードの主要な部分について説明します。
Form1
デザイン画面

Form1 クラス
Form1はメインフォームを表し、Formクラスから派生しています。- コンストラクタ (
public Form1()) 内で、InitializeComponent()メソッドを呼び出してフォームの初期化を行っています。これはデザイナーによって生成されたコードで、フォーム上のコントロールの配置やプロパティの設定を含みます。 - その後、
SubFormインスタンスを作成し、SubFormから発行されるOnButtonClickedイベントにCheckSubFormメソッドをイベントハンドラとして登録しています。これにより、サブフォーム上の特定のボタンがクリックされたときにCheckSubFormメソッドが呼び出されるように設定されています。 CheckSubFormメソッドでは、メインフォーム上のラベル (label1) のテキストを変更して、サブフォームのボタンが押されたことを示しています。
// メインフォームのクラス定義
public partial class Form1 : Form
{
// Form1のコンストラクタ
public Form1()
{
InitializeComponent(); // フォームの初期設定を行うメソッド
// サブフォームのインスタンスを作成
SubForm subForm = new SubForm();
// サブフォームのボタンクリックイベントにイベントハンドラを登録
subForm.OnButtonClicked += CheckSubForm;
// サブフォームを表示
subForm.Show();
}
// サブフォームのボタンがクリックされた時に呼び出されるメソッド
public void CheckSubForm()
{
// メインフォーム上のラベルのテキストを変更
label1.Text = "サブフォームのボタンが押された";
}
}
SubForm
デザイン画面

button1コントロールのイベントハンドラの登録

SubForm クラス
SubFormはサブフォームを表し、同様にFormクラスから派生しています。- このクラスでは、
OnButtonClickedというAction型のイベントを公開しています。これは、サブフォーム上の特定のボタンがクリックされたことを外部に通知するためのイベントです。 - イベントハンドラ
OnSubFormButtonClickedは、サブフォーム上のボタンがクリックされたときに呼び出されるメソッドです。このメソッド内で、OnButtonClickedイベントが null でないかをチェックし(null 条件演算子?.を使用)、null でない場合にイベントを発火 (Invoke()) しています。これにより、イベントに登録されたすべてのハンドラ(この場合はForm1のCheckSubFormメソッド)が呼び出されます。
// サブフォームのクラス定義
public partial class SubForm : Form
{
// サブフォームのボタンクリックイベントを外部に公開するイベントデリゲート
public event Action OnButtonClicked;
// SubFormのコンストラクタ
public SubForm()
{
InitializeComponent(); // フォームの初期設定を行うメソッド
}
// サブフォームのボタンがクリックされた時に呼び出されるイベントハンドラ
private void OnSubFormButtonClicked(object sender, EventArgs e)
{
// イベントがnullでないかチェックしてからイベントを発生
OnButtonClicked?.Invoke();
}
}
実行結果
- アプリケーションが開始され、
Form1のインスタンスが作成されます。 Form1のコンストラクタが呼ばれ、InitializeComponent()が実行されます。これにより、フォーム上のコントロール(例えばlabel1など)が配置されます。- コンストラクタ内で
SubFormのインスタンスが生成され、OnButtonClickedイベントにCheckSubFormメソッドがイベントハンドラとして関連付けられます。 SubFormが表示されます。- ユーザーが
SubForm上のボタン(おそらくbutton1と名付けられたボタン)をクリックします。 - ボタンのクリックイベントが
OnSubFormButtonClickedメソッドをトリガーし、そのメソッド内でOnButtonClickedイベントが発火します(。 OnButtonClickedイベントの発火により、Form1のCheckSubFormメソッドが呼び出されます。CheckSubFormメソッドによって、Form1上のlabel1のテキストが「サブフォームのボタンが押された」という文字列に変更されます。
実行結果として、ユーザーが SubForm のボタンをクリックすると、Form1 上の label1 が新しいテキストで更新され、ユーザーにアクションが行われたことが視覚的にフィードバックされることになります。
サンプルの構成(データを渡したい場合)
このサンプルは、Windows Forms アプリケーションでカスタムイベント引数を持つイベントの使用方法を示すものです。Form1 クラスと SubForm クラス、およびカスタムイベント引数を定義する MyEventArgs クラスで構成されています。
Form1
デザイン画面

Form1 クラス
Form1はSystem.Windows.Forms.Formクラスを継承しています。これは、Windows Forms アプリケーションでウィンドウ(フォーム)を作成するための基本クラスです。- コンストラクタ
public Form1()は、フォームがインスタンス化されたときに呼ばれます。 - コンストラクタ内で
InitializeComponent()メソッドが呼ばれることにより、フォーム上のコントロール(この場合はおそらくlabel1)の初期設定が行われます。 - 新たに
SubFormインスタンスが作成され、subForm.OnButtonClickedというイベントにCheckSubFormメソッドがイベントハンドラとして登録されます。これにより、サブフォームで定義されたイベントが発生した際に、Form1のCheckSubFormメソッドが呼び出されるようになります。 subForm.Show();により、サブフォームが表示されます。CheckSubFormメソッドは、SubFormからのイベントを受け取り、label1のテキストを更新します。ここでイベントの引数としてMyEventArgsクラスのインスタンスが渡され、そのHpプロパティの値をラベルに表示します。
using System.Windows.Forms;
namespace FormComSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SubForm subForm = new SubForm();
subForm.OnButtonClicked += CheckSubForm;
subForm.Show();
}
private void CheckSubForm(object sender, MyEventArgs e)
{
label1.Text = $"サブフォームのボタンが押された {e.Hp}";
}
}
}
SubForm
デザイン画面

このサンプルでは、button1コントロールのイベントハンドラの登録はコードで実現していますので不要です
SubForm クラスと MyEventArgs クラス
SubFormもまたFormクラスを継承しています。SubFormにはEventHandler<MyEventArgs>デリゲートを使ったOnButtonClickedというイベントが定義されています。このイベントはSubFormのボタンがクリックされた時に発生します。button1.Clickイベントハンドラは匿名メソッドを使用しており、ボタンがクリックされるとMyEventArgsインスタンスを新規作成し、Hpプロパティに100を設定してからOnButtonClickedイベントを発火させます。MyEventArgsはEventArgsクラスから派生していて、Hpという追加の情報をイベントと共に送ることができます。
このコードの全体的な流れは、Form1 が起動するとすぐに SubForm を表示し、サブフォーム上のボタンがクリックされたときにメインフォームの label1 を更新して、「サブフォームのボタンが押された」と表示するとともに、Hp の値を表示するというものです。
using System;
using System.Windows.Forms;
namespace FormComSample
{
public partial class SubForm : Form
{
public event EventHandler<MyEventArgs> OnButtonClicked;
public SubForm()
{
InitializeComponent();
button1.Click += (s, e) =>
{
MyEventArgs args = new MyEventArgs();
args.Hp = 100;
// nullチェックを追加
OnButtonClicked?.Invoke(this, args);
};
}
}
public class MyEventArgs : EventArgs
{
public int Hp;
}
}
実行結果
- アプリケーションが起動され、
Form1のインスタンスが作成されます。 Form1のコンストラクタが実行され、InitializeComponentメソッドを通じてフォーム上のコントロールが初期化されます。SubFormの新しいインスタンスが作成され、OnButtonClickedイベントに対してCheckSubFormメソッドがイベントハンドラとして登録されます。subForm.Show()が呼び出され、サブフォームが表示されます。- ユーザーが
SubForm上のbutton1をクリックすると、button1.Clickイベントに関連付けられた匿名メソッドが実行されます。 - 匿名メソッド内で
MyEventArgsインスタンスが生成され、Hpプロパティに100が設定されます。 OnButtonClickedイベントが発火され、Form1のCheckSubFormメソッドがコールバックとして呼び出されます。CheckSubFormメソッドがlabel1のテキストを更新し、サブフォームのボタンが押されたことと、Hpの値(この例では100)が表示されます。
結果として、Form1 上の label1 には "サブフォームのボタンが押された 100" というテキストが表示されることになります。これにより、サブフォームでのユーザーのアクションがメインフォームに伝えられ、その結果がメインフォーム上でユーザーにフィードバックされます。






ディスカッション
コメント一覧
まだ、コメントがありません