ここまでのサンプルではフォームの内容が固定的に記述されていたが、実際のWebアプリケーションでは、リスト・ボックスに表示される項目や、チェック・ボックスのチェック状態などが動的に決められるケースの方が多いはずだ。そこで、次にフォームの初期化に利用するPage_Loadイベントについて解説する。リスト3.2では、いままでasp:ListItemコントロールで静的に定義していたリスト・ボックスの項目をプログラム・コードで登録している。
1: <%@ PAGE LANGUAGE="C#" %>
2: <html>
3: <script runat="server">
4: void Page_Load(object sender, EventArgs e) {
5: lb_Address.Items.Clear();
6: lb_Address.Items.Add(new ListItem("東京"));
7: lb_Address.Items.Add(new ListItem("神奈川"));
8: lb_Address.Items.Add(new ListItem("千葉"));
9: lb_Address.Items.Add(new ListItem("埼玉"));
10: }
11:
12: void submit_click(object sender, EventArgs e) {
13: if (lb_Address.SelectedIndex > -1) {
14: tb_Name.Text = lb_Address.SelectedItem.Text;
15: } else {
16: tb_Name.Text = "unselected";
17: }
18: }
19: </script>
20: <body>
21: <form runat="server">
22: <asp:ListBox id="lb_Address" runat="server">
23: </asp:ListBox>
24: <asp:TextBox id="tb_Name" runat="server" />
25: <asp:Button Text="Submit" OnClick="submit_click" runat="server" />
26: </form>
27: </body>
28: </html>
sample04.aspxの実行(www.iwebmethod.netのページ)
■Page_Loadメソッド
ASP.NETページがリクエストされた直後に呼び出されるのが、Page_Loadイベントに対応するPage_Loadメソッドである。このメソッドは、通常のアクセスか、ポストバックによるアクセスかによらず、リクエストのたびに必ず呼び出される。
Page_Loadメソッドもイベント・ハンドラとして定義されているため、そのほかのすべてのイベント・ハンドラと同じく、次のように2つの引数を持つメソッドとして定義する。Page_Loadメソッドは、定義されていれば自動的に呼び出されるため、特にイベントの設定は不要だ。
4: void Page_Load(object sender, EventArgs e) {
■リスト・ボックスの初期化
まずコードを見る前にフォームの中身に目を向けてもらおう。するといままでasp:ListBoxコントロール内部に記述されていたasp:ListItemコントロールがなくなっていることが分かるだろう。今回はこの項目を次のようにして、コードを用いて登録している。登録される項目は、いままでのasp:ListItemコントロールとまったく同じ内容になっている。
5: lb_Address.Items.Clear();
6: lb_Address.Items.Add(new ListItem("東京"));
ここではまずListBox.ItemsプロパティのClearメソッドを呼び出し、リスト・ボックスを空にしている。リスト・ボックスの内容はビュー・ステートの働きによって維持され、Page_Loadメソッドがリクエストのたびに呼び出されるので、こうしておかないとポストバックするたびに、項目が4つずつ追加されていってしまうからだ。こうしてクリアした後は、ListBox.ItemsプロパティのAddメソッドを呼び出し、リスト・アイテムを1つずつ登録している。
ところで、リスト・ボックスへの項目の追加は、よりスマートに、次のように記述することも可能だ。このDataSourceプロパティとDataBindメソッドによるデータ登録の仕組みは「データ連結」と呼ばれ、さまざまなコレクションを用いて、サーバ・コントロールの状態をコントロールする統一的な仕組みとして設計されている。データ連結の詳細は、各種サーバ・コントロールの解説を終えた後に解説する。
void Page_Load(object sender, EventArgs e) {
String[] s = new String[] { "東京", "神奈川", "千葉", "埼玉" };
lb_Address.DataSource = s;
lb_Address.DataBind();
}
リスト3.2を実行すると、リスト・ボックスへの項目追加はうまくいくが、ボタンをクリックすると、テキスト・ボックスには必ず“unselected”が表示され、リスト・ボックスの項目も選択解除されてしまうことに気付いただろうか。まるでASP.NETページの基本サービスである自動状態管理が機能していないかのようだが、実はPage_Loadメソッドでの処理がリスト・ボックスを初期化してしまい、ポストバックされた情報を上書きしているにすぎない。
ASP.NETページがリクエストされると、次の順序で処理が行われる。サーバ・コントロールの状態復元の後に、Page_Loadメソッドが呼び出されていることに注目してほしい。
つまり、せっかく復元されたリスト・ボックスの状態は、Items.Clearメソッドの呼び出しによってクリアされてしまうため、submit_clickイベント・ハンドラが呼び出されるときには、どの項目も選択されていない状態と判断されてしまうわけだ。
これを回避するには、初めてページがリクエストされたときにだけ、サーバ・コントロールの初期化を行い、以後ポストバックされたときには実行されないようにしなければならない。この目的で用意されているプロパティがIsPostBackである。これはポストバックによってリクエストされたときにだけtrueとなる、bool型のプロパティである。このプロパティを使って、Page_Loadメソッドを次のように書き直せば、無駄にリスト・ボックスが初期化され、自動状態管理が無効化されることを避けられる。
void Page_Load() {
if (!IsPostBack) {
lb_Address.Items.Clear();
lb_Address.Items.Add(new ListItem("東京"));
lb_Address.Items.Add(new ListItem("神奈川"));
lb_Address.Items.Add(new ListItem("千葉"));
lb_Address.Items.Add(new ListItem("埼玉"));
}
}
Page_Loadメソッドでは、このようにIsPostBackプロパティを利用して、非ポストバック時にのみ初期化処理を行うのが常とう手段となっている。
ところで、突然登場したIsPostBackプロパティだが、これはSystem.Web.UI.Pageクラス・メンバとして定義されているプロパティである。なぜそれがここでアクセス可能であるかというと、ASP.NETページのコード宣言ブロックにコードを記述すると、自動的にPageクラスの派生クラスが定義され、コード宣言ブロックで定義されたメソッドはすべてこの無名の派生クラス(内部的にはもちろん名前を持つ)のメンバとして定義される仕組みになっているからだ。次回はこのASP.NETページのフレームワークとなるPageクラスについて解説する。
Copyright© Digital Advantage Corp. All Rights Reserved.