イベントハンドラの引数

Visual C# で新しいプロジェクトを作って、フォームデザイナで何もないフォームの上にツールボックスからボタンを一個だけ貼り付けてみよう。作製された button1 を選択してダブルクリックすると、Form1.cs が開かれてbutton1 の Click に対応するシグラナルハンドラ、

private void button1_Click(object sender, EventArgs e)

が、自動的に作成されている。ここに、ボタンがクリックされた時のプログラムを記述していけばいいのだが、このイベントハンドらには、object 型の sender と EventArgs 型の e という二つの引数が渡されている。

どんな引数が返されているかを調べるには、オブジェクトのToString() メソッドを利用するのが便利だ。

例えば、sender の内容を知るためには、Form1 に texBox を追加したあと、、button1 のイベントハンドラに、

textBox1.Text = sender.ToString();

とプログラムして、[デバッグ] - [デバッグ開始] メニューでプログラムを実行する。ボタンをクリックすると、textBox1 に、

System.Windows.Forms.Button, Text: button1

と表示される。どうやら、button1 のオブジェクトが渡されているらしい。しかし、Button オブジェクトとしてではなく、object 型で渡されているため、

textBox1.Text = sender.Text;

としてもビルドエラーがでてしまう。派生クラスが抽象クラスとして扱われているときは、キャストすれば派生クラスを取り出すことができる。 button1_Click() イベントハンドラに、

textBox1.Text = ((Button)sender).Text;

と記述すると、ボタンのクリックでテキストボックスに button1 の文字が表示される。

イベントハンドラのような汎用性のあるメソッドに渡す引数は、抽象クラスのオブジェクトで渡した方が汎用性を保てるのだろう。こういうときは、プログラムする方で型変換を行わなければならないが、抽象クラスから派生クラスを取り出すのは、C# では単にキャストするだけでよいようだ。

もう一つの変数 EventArgs e についても調べてみた。

イベントハンドラのプログラムが、

textBox1.Text = e.ToString();

のときは、テキストボックスに System.Windows.Forms.MouseEventArgs と表示されたので、

textBox1.Text = ((MouseEventArgs)e).Button.ToString();

で、試すと Left と表示された。Left を調べてみたら、System.Windows.Form.MouseButtons 列挙型のメンバだったので、button1_Click イベントハンドラに次のようなプログラムを書き込んだらビルドエラーになった。

if (((MouseEventArgs)e).Button == MouseButtons.Left)
{
    textBox1.Text = "OK";
{

そこで、MouseButtons.Left をフルパス表記して、

if (((MouseEventArgs)e).Button == System.Windows.Forms.MouseButtons.Left)

にしたら、無事にビルドできて button1 のクリックでテキストボックスに OK が表示された。using 文を使っても定数についてはフルパス表記しないといけないらしい。

using を使っても定数はフルパス表記しないとビルドできないなどとはマニュアルにも書いてないので、実験して始めて分かった。これが大きいプログラムを書いた後だったら頭を抱えてしまったかもしれない。こういう単純なプログラムについて十分実験してみるというのは、新しいプログラム言語に挑戦するときには有効な方法だ。

プログラム言語を習得するときには、文法について学ぶだけでなく、言語の作者がどういう意図でそのような文法をつくったかという発想にまで思い至らないとなかなか使いこなせない。きちんと動いている小さいプログラムについてこういう風にいろいろと実験をしかけてみるのは、プログラム言語の発想を知るためによい方法だと思う。
[PR]
by tnomura9 | 2010-01-29 10:54 | C# | Comments(0)
<< プログラムファイルの構成 メニューを作る >>