.NET ROOM.NET ROOMトップへCOMRADE総合トップへ
「2:イベントハンドラの登録と独自イベントの作成」へ



2:イベントハンドラの登録と独自イベントの作成

 ・はじめに
 ・イベントハンドラの登録
 ・イベントを登録?
 ・独自イベントの作成
 ・自作イベントの使用法
 ・最後に
 ・キャスト

 ◆付録 (本稿で取り上げたソースコードおよびサンプルプログラム)
   \DigitTextForm
     「イベントハンドラの登録」サンプル
   \ExtendedNumericUpDown
     「独自イベントの作成」サンプル

はじめに

 前回は、TextBoxコントロールを拡張し、数字以外の入力を受け付けないコ ントロールを作成しながら、
プロパティやメソッドのオーバーライドによる処理の変更と、イベントの処理に関して簡単に触れました。
今回は、より詳しくイベントに関して説明してゆくことにします。

今回は最初にイベントハンドラの登録に関して説明し、その後独自イベントの実装および使用方法を説明します。



イベントハンドラの登録

 イベントを処理するメソッドのことを「イベントハンドラ」といいます。
TextBoxコントロールのKeyPressイベントなら、前回のように、派生クラスを作成し、
OnKeyPressメソッドをオーバーライドすることができます。
しかし、派生クラスが作れないSealedクラスのコントロールや、処理を記述したいイベントに対応する
OnXXXXメソッドがないなど、オーバーライドできない場合には、
今回説明するイベントハンドラの登録を使用することになります。
なおイベントハンドラの登録の説明には、前回に引き続き、TextBoxコントロールを使用します。

登録の手順


 前回同様、「新しいプロジェクト」ダ イアログで「Visual C#プロジェクト」 のテンプレートから
「Windowsアプリ ケーション」を選択し、プロジェクト 名を付けて[OK]ボタンを押し、新し いプロジェクトを作成します。

 Form1.csのデザイン画面が現われるので、ツールボックスから「TextBox」を選択して、フォームにドラッグします。

  「textBox1」というTextBoxがForm1上に作成されます。このtextBox1を選択して、右クリックすると表示される
ショートカットメニューから[プロパティ]を選択します。プロパティウィンドウが表示されるので、前回と同様、
イベント一覧ボタンをクリックし、イベントのプロパティを表示します。

  アイコンをクリックした直後は「プロパティ変更」というカテゴリのTextChangedイベントにカーソルがあるので、
上のほうにある「キー」というカテゴリの中から、目的のKeyPressイベントを選択します(図1)。
KeyPressイベントをダブルクリックすると、「textBox1_KeyPress」というメソッドが自動生成されます。

図1:プロパティウィンドウでイベントを表示図



 コードエディタで「Windowsフォームデザイナで生成されたコード」の左側にある[+]部分をクリックすると、
「#region……#endregion」というコードで記述された、一時的に隠れていた部分が開きます。
textBox1_KeyPressの生成と同時に、textBox1_KeyPressがKeyPressイベントに登録されたことが確認できます。

   //
   // textBox1
   //
   (略)
   this.textBox1.KeyPress +=
    new System.Windows.Forms.KeyPressEventHandler(
    this.textBox1_KeyPress);

 次にここで自動的に行なわれた、イベントの登録に関して説明してゆくことにします。


自分好みの
 デフォルトの設定では#regionの部分は、閉じた状態で表示されます。
もしこの隠れた部分を常に開いておきたいのであれば、[ツール]メニューから[オプション]を選択して「オプション」ダイアログを表示します。
そして、ダイアログの左側のツリーを「テキストエディタ」→「C#」→「書式設定」の順でたどり、「ファイルを開いたときに#regionブロックを縮小する」というチェックを外せば、#regionブロックを開いた状態でコードを表示することができます。
「オプション」ダイアログには、このほか、タブ幅の設定や、行数の表示などさまざまな設定があるので、自分好みにカスタマイズするのも面白いでしょう。



ページトップへ


イベントを登録?

 前述の手順により、Visual Studio .NETがイベントハンドラを自動生成して、
イベントに登録できることがわかりましたが、
ここではその自動生成されたKeyPressイベントに関して説明します。

 KeyPressイベントは、C#では以下のように宣言されています。

    public event KeyPressEventHandler KeyPress;

    さらに、KeyPressEventHandlerの定義は、

   public delegate void KeyPressEventHandler(
    object sender, KeyPressEventArgs e
   );

 となっています。

 ここからわかるとおり、KeyPressイベントの実体は、「KeyPressEventHandler」というデリゲートになっています。
デリゲートを使用するには、同じ引数のメソッドを作成します。
このメソッドに、前回OnKeyPressメソていた処理を記述します(リスト1)。

リスト1:KeyPressイベントのハンドラ
private void textBox1_KeyPress(object sender, KeyPressEventArgs e) {
 char c = e.KeyChar;
 const char BACKSPACE = '\b';
 if (!char.IsDigit(c) && c != BACKSPACE) {
  e.Handled = true;
  return;
 }
}


これで、前回派生クラスを作成して行なっていたKeyPressイベントの処理を、デフォルトのTextBoxだけを
使用して実現する方法がわかりました。

 続いて、前回TextプロパティのSetアクセサをオーバーライドして行なっていた
「コードからの代入を阻止する部分」の実装を説明します。

 まず、先ほどのKeyPressイベントと同様に、Visual Studio .NETを使用して、
textBox1のTextChangedイベントを自動生成します。
ただし、TextChangedイベントは、Textプロパティが変更され終わったときに発生するため、
前回のTextプロパティのオーバーライドのように、途中で処理を中断することはできません
(すでにTextプロパティは代入済みです)。
そのため、前回のTextプロパティの値を保持するためのフィールドを設けました。

 リスト2にtextBox1_TextChangedメソッドを示します。
isNumericStringメソッドの処理は、前回と同じなので省略します。
詳細は付録に収録しているソースコードを参照してください。

  続いて、独自のイベントに関して説明してゆきます。

リスト2:TextChangedイベントのハンドラ
private string validText = "";
private void textBox1_TextChanged(object sender, EventArgs e) {
 string text = textBox1.Text;
 if (!isNumericString(text))
  textBox1.Text = validText;
 else
  validText = textBox1.Text;
}


注意
 リスト2の方法を応用すれば、標準のTextBoxを使用して入力制御をすることができますが、
.NET標準のTextBoxコントロールには、前回説明したようにバグがあり、IME経由の入力を弾くことはできません。



.NET Roomトップへ | ページトップへ | 次へ