ASP.NETでは、Webページ上のコントロールが操作されたときに実行されるイベント・ハンドラを、サーバ側で記述することができる。
前回のサンプル・プログラムを引き続き拡張し、ボタンがクリックされると、リスト・ボックスで選択した項目がテキスト・ボックスにコピーされるようにしてみよう(リスト3.1)。この処理を実現するには、フォームからポストバックされた情報を受け取り、テキスト・ボックスにテキストを代入するようなサーバ・サイドのプログラムが必要になる。
このような処理は、サーバ・コントロールの操作に対応するイベント・ハンドラを定義することによって実現される。
1: <%@ PAGE LANGUAGE="C#" %>
2: <html>
3: <script runat="server">
4: void submit_click(object sender, EventArgs e) {
5: if (lb_Address.SelectedIndex > -1) {
6: tb_Name.Text = lb_Address.SelectedItem.Text;
7: } else {
8: tb_Name.Text = "unselected";
9: }
10: }
11: </script>
12: <body>
13: <form runat="server">
14: <asp:ListBox id="lb_Address" runat="server">
15: <asp:ListItem>東京</asp:ListItem>
16: <asp:ListItem>神奈川</asp:ListItem>
17: <asp:ListItem>千葉</asp:ListItem>
18: <asp:ListItem>埼玉</asp:ListItem>
19: </asp:ListBox>
20: <asp:TextBox id="tb_Name" runat="server" />
21: <asp:Button Text="Submit" OnClick="submit_click" runat="server" />
22: </form>
23: </body>
24: </html>
sample03.aspxの実行(www.iwebmethod.netのページ)
ボタンのクリックに対するイベント・ハンドラを定義するには、次のコードが必要になる。
1. @Pageディレクティブで使用言語を指定する
まず.aspxファイルの先頭に次の1行を追加して、イベント・ハンドラのコードをC#で記述することを宣言する(先頭である必要はないが、先頭に記述するのが一般的)。
1: <%@ PAGE LANGUAGE="C#" %>
「<%@ 〜 %>」で囲まれたブロックはディレクティブ・ブロックと呼ばれ、ページ全体に対する設定の変更などを行う。ASP.NETにおける、C言語の「#includeディレクティブ」や「#defineディレクティブ」のようなものだと考えればよい。ASP.NETでは@Page以外にも、@Importや@Registerなど、8種類のディレクティブが定義されている。これらのディレクティブは、サンプルにある@Pageディレクティブのlanguage属性のように、それぞれが固有の属性を持ち、ASP.NETページの設定に利用される。ディレクティブの詳細については、いずれ解説する。
なお、ディレクティブ名は本来“Page”や“Import”であるはずだが、文章中では、ディレクティブ名であることを明確にするために、ディレクティブ・ブロックの開始タグの一部である“@”(アットマーク)を含めて、“@Page”や“@Import”のように記述するのが一般的だ。
2. サーバ・コントロールのID属性でオブジェクト名を定義する
次に、イベント・ハンドラからアクセスするサーバ・コントロールにID属性を設定する。このサンプルでは、リスト・ボックスで選択した項目のテキストをテキスト・ボックスにコピーするので、次のように2つのサーバ・コントロールにIDを設定する。
14: <asp:ListBox id="lb_Address" runat="server">
・・・・
20: <asp:TextBox id="tb_Name" runat="server" />
これによって、scriptブロックに記述したプログラムから、lb_Addressとtb_Nameがそれぞれオブジェクトとしてアクセス可能となり、リスト・ボックスで選択された項目やテキスト・ボックスに入力された文字列を操作できるようになる。これらオブジェクトのデータ型は、サーバ・コントロールの種類によって決定され、asp:ListBoxコントロールはListBoxクラスに、asp:TextBoxコントロールはTextBoxクラスにそれぞれ対応している。
3. サーバ・コントロールのOnClick属性でイベント・ハンドラとなるメソッドを指定する
フォームからポストバックを発生させ、イベント・ハンドラを呼び出すには、asp:Buttonサーバ・コントロールのOnClick属性に、イベント・ハンドラとして定義されたメソッド名を指定する。ここではsubmit_clickメソッドがイベント・ハンドラとして指定されている。
21: <asp:Button Text="Submit" OnClick="submit_click" runat="server" />
asp:Buttonコントロール以外のサーバ・コントロールにも、OnClick属性のようなイベント・ハンドラを登録する属性が定義されているが、asp:ButtonコントロールのOnClick属性は特別な存在だ。
通常、フォームからポストバックを発生させる方法は、Submitボタンをクリックする以外にないからだ。つまり、asp:Buttonコントロールにイベント・ハンドラが設定されていなければ、そのほかのサーバ・コントロールにイベント・ハンドラが登録されていても、ポストバックを発生させることができず、結果としてサーバ・サイドのコードが実行されることはない。
また、asp:Buttonコントロール以外のサーバ・コントロールにイベント・ハンドラを登録し、イベントが発生する操作を行っても(例:asp:ListBoxコントロールにOnSelectedIndexChanged属性を指定して、リスト・ボックスで項目を選択する)、ポストバックは発生しない。こうしたイベントは、Submitされたときに、1回のポストバックでまとめて処理されることになっている。従って、フォームにasp:Buttonコントロールは必須である。
ただし、上記の動作はデフォルト設定のもので、ASP.NETではちょっとしたトリックを用いて、asp:Buttonコントロール以外でも、ポストバックを発生させることを可能としているので、実際にはasp:Buttonコントロールが必須というわけではない(この機能はクライアントに依存するため、常に利用できるわけではないが)。このあたりのイベント発生メカニズムの詳細については、次回以降で詳しく解説していく。
4. <script runat="server">にサーバ・サイド・プログラムを記述する
サーバ・サイドで実行されるプログラムは、サーバ・コントロールと同じく、「runat="server"」属性を持つscriptエレメントに記述する。これを「コード宣言ブロック」と呼ぶ。このscriptタグのlanguage属性で使用言語を指定できるが、ASP.NETページでは同一ページに複数の言語を混在させることはできないので、@Pageディレクティブで指定すれば以後コード宣言ブロックごとに指定する意味はない。
3: <script runat="server">
4: void submit_click(object sender, EventArgs e) {
5: if (lb_Address.SelectedIndex > -1) {
6: tb_Name.Text = lb_Address.SelectedItem.Text;
7: } else {
8: tb_Name.Text = "unselected";
9: }
10: }
11: </script>
ここでは、asp:ButtonコントロールのOnClick属性に指定した名前(submit_click)でイベント・ハンドラを定義している。一般的にイベント・ハンドラの名前には“<ID>_<イベント名>”の形式が用いられるが、特に決められているわけではない。
一方、イベント・ハンドラの戻り値の型と引数は次のように決められている。第1引数senderにはイベントを発生させたサーバ・コントロールが、第2引数eにはイベントに関連する情報がそれぞれ格納され、メソッドが呼び出される。ただしEventArgsクラスには特に有益な情報は格納されておらず、実際にはイベントごとに多数定義されているEventArgsクラスの派生クラスを指定して利用する。イベント情報が不要であれば、サンプルのようにEventArgsクラスを指定すればよい。
void <メソッド名>(object sender, EventArgs e)
イベント・ハンドラ内部では、サーバ・コントロールに指定したIDを基に、サーバ・コントロールのプロパティへアクセスし、リスト・ボックスで項目が選択されていればテキスト・ボックスに文字列をコピーし、選択されていなければ文字列“unselected”を代入する処理を行っている。このとき、asp:ListBoxコントロールに指定されたlb_AddressにはSystem.Web.UI.WebControls.ListBoxクラスのオブジェクトが、asp:TextBoxコントロールに指定されたtb_NameにはSystem.Web.UI.WebControls.TextBoxクラスのオブジェクトがそれぞれ格納されている。これらのオブジェクトを通してサーバ・コントロールのプロパティを操作すれば、イベント・ハンドラの処理を終えた後に生成されるレスポンスHTMLに反映される。
Copyright© Digital Advantage Corp. All Rights Reserved.