イベントハンドラとはなんぞや。
イベントハンドラは、デリゲートです。
(デリゲートよく分からねーって人はコチラ。)
百聞は一見に如かず。
まずは、Windowsフォームアプリケーションを作成して、Formにボタンをひとつ配置して、ボタンをダブルクリックするなりしてイベントハンドラを自動生成し、MessageBoxを置く。
ボタンを押せば、Hellowとメッセージボックスが開く。
private void button1_Click(object sender, EventArgs e) { MessageBox.Show("Hellow"); }
ところで、このbutton1_Clickメソッドはなぜ、動くのか。
このメソッドを参照すると、下記のようにコードが自動生成されている。
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Clickとやらに EventHandlerのインスタンスを渡している。
つまり、button1.ClickもEventHandler型を受け取れるものだということ。
んで、このEventHandlerはなんぞってことでさらに追いかけると、
namespace System { // 概要: // イベント データを持たないイベントを処理するメソッドを表します。 // // パラメーター: // sender: // イベントのソース。 // // e: // イベント データを格納している System.EventArgs。 [Serializable] [ComVisible(true)] public delegate void EventHandler(object sender, EventArgs e); }
namespace System の上記までやってきた。
読み解くと、EventHandlerは、void型で、引数にobject型とEventArgs型をもつ、delegateとある。
つまり、ボタンはClickというデリゲート型の変数を持ち、その変数はEventHandlerというデリゲート型である。
以前の記事で、デリゲートとは、関数を覚えられる変数のようなものであると書いた。
ためしに、同じvoid型で、引数にobject型とEventArgs型をもつ関数を作ってみる。
private void SayWorld(object sender, EventArgs e) { MessageBox.Show("World"); }
そして、これをボタンのClickに代入する。
public Form1() { InitializeComponent(); this.button1.Click += this.SayWorld; }
実行すると、HellowのあとにWorldとメッセージボックスが表示される。(+=で追加代入したから)
//1 this.button1.Click += this.SayWorld; //2 this.button1.Click += new EventHandler(this.SayWorld);
ちなみに、1の書き方と2の書き方がある。2は自動生成されるときに書かれている省略しない書き方。
自前で書くときは1で書く人が多いイメージ。
また、このClickという関数の定義を見ると、
// // 概要: // コントロールがクリックされたときに発生します。 public event EventHandler Click;
とある。
なぜ、クリックするとこのClickが実行されるかは、イベントドリブン方式といって・・・、まぁ、そいうものだと理解する。
まとめると、
ボタンがクリックされると、イベントハンドラという名前のデリゲートが実行される。
デリゲートは関数を覚えられる変数だから、あらかじめ代入されていた関数が実行される。
ただ、それだけの話。
これで、イベントハンドラが何かざっくりと分かったんではないだろうか。
そして、このイベントハンドラをラムダ式でシンプルに書きたい場合は、前に書いた下記の記事が参考になると思う。
イベントハンドラとラムダ式