第17章 言語に内蔵されたイベント機能:連載 改訂版 C#入門(4/4 ページ)
C#のイベントは、あるクラスで発生した事象をほかのクラスに伝達する。この機能は、キーボードやマウスによるイベントの処理にもぴったりマッチする。
17-8 ウィンドウにおけるイベントの使われ方
イベントが最も活躍するのはウィンドウのイベント処理だろう。実際の使われ方を見てみよう。List 17-10のサンプルは以下のように作成している。まず、新規プロジェクトで、Windowsアプリケーションを選ぶ。そして、フォーム上にボタンを1個貼り付ける。Fig.17-8を参照されたい。
そして、貼り付けたボタンをダブルクリックしてハンドラを追加するとともにコードウィンドウを開き、List 17-10の90行目の内容を書き込めば完成である。
1: using System;
2: using System.Drawing;
3: using System.Collections;
4: using System.ComponentModel;
5: using System.Windows.Forms;
6: using System.Data;
7:
8: namespace Sample010
9: {
10: /// <summary>
11: /// Form1 の概要の説明です。
12: /// </summary>
13: public class Form1 : System.Windows.Forms.Form
14: {
15: private System.Windows.Forms.Button button1;
16: /// <summary>
17: /// 必要なデザイナ変数です。
18: /// </summary>
19: private System.ComponentModel.Container components = null;
20:
21: public Form1()
22: {
23: //
24: // Windows フォーム デザイナ サポートに必要です。
25: //
26: InitializeComponent();
27:
28: //
29: // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
30: //
31: }
32:
33: /// <summary>
34: /// 使用されているリソースに後処理を実行します。
35: /// </summary>
36: protected override void Dispose( bool disposing )
37: {
38: if( disposing )
39: {
40: if (components != null)
41: {
42: components.Dispose();
43: }
44: }
45: base.Dispose( disposing );
46: }
47:
48: #region Windows Form Designer generated code
49: /// <summary>
50: /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
51: /// コード エディタで変更しないでください。
52: /// </summary>
53: private void InitializeComponent()
54: {
55: this.button1 = new System.Windows.Forms.Button();
56: this.SuspendLayout();
57: //
58: // button1
59: //
60: this.button1.Location = new System.Drawing.Point(104, 88);
61: this.button1.Name = "button1";
62: this.button1.TabIndex = 0;
63: this.button1.Text = "button1";
64: this.button1.Click += new System.EventHandler(this.button1_Click);
65: //
66: // Form1
67: //
68: this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
69: this.ClientSize = new System.Drawing.Size(292, 273);
70: this.Controls.AddRange(new System.Windows.Forms.Control[] {
71: this.button1});
72: this.Name = "Form1";
73: this.Text = "Form1";
74: this.ResumeLayout(false);
75:
76: }
77: #endregion
78:
79: /// <summary>
80: /// アプリケーションのメイン エントリ ポイントです。
81: /// </summary>
82: [STAThread]
83: static void Main()
84: {
85: Application.Run(new Form1());
86: }
87:
88: private void button1_Click(object sender, System.EventArgs e)
89: {
90: MessageBox.Show(this,"Clicked!");
91: }
92: }
93: }
これを実行するとFig.17-9のようになる。
Fig.17-9のボタンを押すと、Fig.17-10のメッセージが出力される。
さて、ソース・コードを解説しよう。このソース・コードでは、ボタンが押されるということを、イベントを用いて伝達する機能を持っている。イベントは、ボタンの機能を持つSystem.Windows.Forms.Buttonというクラスが持っているので、このソース・コード上には記述されていない。15行目の定義により、System.Windows.Forms.Buttonクラスのインスタンスbutton1が用意されている。このbutton1を通じて、イベントにアクセスすることになる。実際にアクセスしているのは64行目である。「this.button1.Click += new System.EventHandler(this.button1_Click);」というコードが、ボタンのClickイベントに、88〜91行目のbutton1_Clickメソッドをハンドラとして登録している。
ここで注目すべきことは、ボタン(System.Windows.Forms.Buttonクラス)のイベントがフォーム(Form1クラス)のメソッドで処理されているという点である。この結果、ユーザー側で記述するコードを、1個所にコンパクトにまとめることが可能となっている。
17-9 複数ボタンに対応するハンドラ
イベントの価値を実感するために、もう1個のサンプル・ソースを見てみよう。まず、上記のサンプルと同様に新しいWindowsプロジェクトを作り、フォーム上に3個のボタンを貼り付ける。Fig.17-11を参照されたい。
そうしたら、List 17-11のサンプル・ソースの30〜32行目と、107〜111行目を入力する。これででき上がりである。
1: using System;
2: using System.Drawing;
3: using System.Collections;
4: using System.ComponentModel;
5: using System.Windows.Forms;
6: using System.Data;
7:
8: namespace Sample011
9: {
10: /// <summary>
11: /// Form1 の概要の説明です。
12: /// </summary>
13: public class Form1 : System.Windows.Forms.Form
14: {
15: private System.Windows.Forms.Button button1;
16: private System.Windows.Forms.Button button2;
17: private System.Windows.Forms.Button button3;
18: /// <summary>
19: /// 必要なデザイナ変数です。
20: /// </summary>
21: private System.ComponentModel.Container components = null;
22:
23: public Form1()
24: {
25: //
26: // Windows フォーム デザイナ サポートに必要です。
27: //
28: InitializeComponent();
29:
30: this.button1.Click += new System.EventHandler(this.all_button_Click);
31: this.button2.Click += new System.EventHandler(this.all_button_Click);
32: this.button3.Click += new System.EventHandler(this.all_button_Click);
33: }
34:
35: /// <summary>
36: /// 使用されているリソースに後処理を実行します。
37: /// </summary>
38: protected override void Dispose( bool disposing )
39: {
40: if( disposing )
41: {
42: if (components != null)
43: {
44: components.Dispose();
45: }
46: }
47: base.Dispose( disposing );
48: }
49:
50: #region Windows Form Designer generated code
51: /// <summary>
52: /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
53: /// コード エディタで変更しないでください。
54: /// </summary>
55: private void InitializeComponent()
56: {
57: this.button1 = new System.Windows.Forms.Button();
58: this.button2 = new System.Windows.Forms.Button();
59: this.button3 = new System.Windows.Forms.Button();
60: this.SuspendLayout();
61: //
62: // button1
63: //
64: this.button1.Location = new System.Drawing.Point(104, 56);
65: this.button1.Name = "button1";
66: this.button1.TabIndex = 0;
67: this.button1.Text = "button1";
68: //
69: // button2
70: //
71: this.button2.Location = new System.Drawing.Point(104, 96);
72: this.button2.Name = "button2";
73: this.button2.TabIndex = 1;
74: this.button2.Text = "button2";
75: //
76: // button3
77: //
78: this.button3.Location = new System.Drawing.Point(104, 136);
79: this.button3.Name = "button3";
80: this.button3.TabIndex = 2;
81: this.button3.Text = "button3";
82: //
83: // Form1
84: //
85: this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
86: this.ClientSize = new System.Drawing.Size(292, 273);
87: this.Controls.AddRange(new System.Windows.Forms.Control[] {
88: this.button3,
89: this.button2,
90: this.button1});
91: this.Name = "Form1";
92: this.Text = "Form1";
93: this.ResumeLayout(false);
94:
95: }
96: #endregion
97:
98: /// <summary>
99: /// アプリケーションのメイン エントリ ポイントです。
100: /// </summary>
101: [STAThread]
102: static void Main()
103: {
104: Application.Run(new Form1());
105: }
106:
107: private void all_button_Click(object sender, System.EventArgs e)
108: {
109: System.Windows.Forms.Button button = (System.Windows.Forms.Button)sender;
110: MessageBox.Show(this,button.Text + " Clicked!");
111: }
112: }
113: }
これを実行するとFig.17-12のようになる。
[button1]ボタンを押すと、Fig.17-13のメッセージが出力される。
まず、30〜32行目に注目していただきたい。これは、ボタンにイベント・ハンドラを登録しているコードである。しかし、3つのボタンのインスタンスに対して、all_button_Clickというたった1つのメソッドをハンドラとして登録してしまっていることが分かるだろう。このようなコードを記述しても問題ない。それは、107〜111行目のall_button_Clickメソッドの内容を見れば分かる。109行目で第1引数のsenderをボタン・クラス(System.Windows.Forms.Button)にキャストしている。ハンドラの第1引数は、イベントを引き起こしたインスタンスなので、当然ボタンのインスタンスである。そのため、キャストは必ずうまくいく。そして、インスタンスへの参照を手に入れれば、ボタンのラベルに書かれた文字列を取得するのは簡単である。Textプロパティを参照するだけでよい。
このように、イベントを使えば、1つのハンドラで異なる複数のインスタンスの処理を引き受けることも容易である。
『新プログラミング環境 C#がわかる+使える』
本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て一部分を転載したものです。
【本連載と書籍の関係について 】
この書籍は、本フォーラムで連載した「C#入門」を大幅に加筆修正し、発行されたものです。連載時はベータ版のVS.NETをベースとしていましたが、書籍ではVS.NET製品版を使ってプログラムの検証などが実施されています。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。
→技術評論社の解説ページ
ご注文はこちらから
Copyright© Digital Advantage Corp. All Rights Reserved.