ScriptManagerコントロールの機能と扱い方
作成されたWebサイト内のDefault.aspxには、デフォルトでScriptManagerコントロールが配置されています(図9)。
このScriptManagerコントロールは、文字通りASP.NET AJAXで使用するスクリプトリソースを管理するコントロールです。AJAX Extensionsを利用する際に必須のコントロールでもあります。これから代表的な機能を紹介していきます。
- AJAX ExtensionsコントロールをJavaScriptに解釈する機能
AJAX Extensionsコントロールの振る舞いはJavaScriptで記述されており、その解釈を自動的に行います。AJAX Extensionsのほとんどのコントロールは、JavaScriptをサーバーサイドからダウンロードしてクライアントサイドで展開しますが、Xml-Scriptでソースを生成した場合には、Xml-ScriptからJavaScriptに解釈する機能も持っています。
- ページの部分更新
ページの部分更新を可能にしているのは
EnabledPartialRenderingプロパティで、デフォルトではTrueになっています。Falseの時には部分更新はできません。この機能のおかげでUpdatePanelコントロールを活用することができます。 - Webサービスとの連携を行う機能
ScriptManagerコントロールのServicesコレクションは、クライアントプロキシオブジェクトを生成して、ランタイムの時に登録されたWebサービスにアクセスします。
- カスタムスクリプトライブラリの取り込み機能
ScriptManagerコントロールのScriptsコレクションは、標準のScriptLibrariesフレームワークに加え、ScriptManagerコントロールがクライアントサイドで利用可能にするカスタム(自前の)スクリプトライブラリも追加することができます。
- Asynchronous Postback(非同期ポストバック)時のエラーハンドリング機能
部分更新が行われている間に
AllowCustomErrorsRedirectプロパティを設定するか、AsyncPostBackErrorMessageプロパティを設定するか、AsyncPostBackErrorイベントを起こすことでエラーハンドリングさせることが可能になります。 - ScriptManagerProxyコントロールの利用
ScriptManagerコントロールが既に使われている場所で利用することが可能な追加定義です。マスタページを適用しているWebページに追加でスクリプトとWebサービスを利用することができます。
- プロファイル機能
ScriptManagerコントロールを利用することでMicrosoft AJAX Libraryが持っているプロファイル機能を利用することができます。
ScriprtManagerコントロールを使う上で、「ページ内に1つしか配置することができない」という点に注意してください。つまり「マスタページを適用したページを作成する際には.aspxファイルではなく、.masterファイルに配置した方が良い」ということになります。もちろん、そのページにしか使わない場合は.aspxファイルに配置しても問題ありませんが、AJAX Extensionsを扱う際にはScriptManagerコントロールの配置方法に注意をしてください。
UpdatePanelコントロールによるページの部分更新
それでは実際にAJAX Extensionsを使用したWebページの構築について説明します。これから使うのはUpdatePanelコントロールというASP.NET AJAXにおいて目玉とも言えるコントロールです。このコントロールの特徴は簡単な設定を行うことで、UpdatePanelコントロール内に配置されているコントロールすべてを、Xml-Httpを利用した非同期通信によるWebページの部分更新をできるようにすることです。このUpdatePanelコントロールは、ScriptManagerコントロールのEnabledPartialRenderingプロパティがTrueに設定されている時に部分更新を可能にします。それではサンプルに入ります。
基本的なUpdatePanelコントロールの使い方(サンプル1)
UpdatePanelコントロール内に表示されているボタンをクリックし、UpdatePanelコントロール内のLabelに「Hello,Ajax」と表示させるWebページを作成します。UpdatePanelコントロールを使用することで、Webページ全体のポストバックではなくUpdatePanelコントロール内の部分更新を行い、画面のちらつきを抑えることができます。
1.フォームデザイナからページをデザインする
ツールボックスから、サーバコントロールを配置します。Label.Textプロパティはブランクに設定しておきます(図11)。
2.UpdatePanelコントロールのプロパティを設定する
プロパティウィンドウからTriggersプロパティの右端の[…]ボタンをクリックします(図12)。
ボタンをクリックすると、図13のようなダイアログが表示されます。初期状態ではメンバには何もありません。左下の[追加]ボタンをクリックするとメンバに[AsyncPostBack:]が追加されます。続いて右側の動作を設定します。ControlIDは[Button1]を、EventNameは[Click]を選択した後でOKボタンをクリックします。この設定を行うことで、UpdatePanelコントロール内にある[Button1]が[Click]された時に、Xml-Httpを利用して[AsynchronousPostBack]が行われるようになります。
3.Labelに「Hello,Ajax」と表示させるコードを書く
デザイン画面に戻った後、ボタンをダブルクリックして次のコードを入力します。
Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Label1.Text = "Hello,Ajax" End Sub
作成したファイルを実行する際にデフォルトのブラウザ以外のブラウザで動作を確認したい場合は、実行したいファイル(Default.aspxなど)上で右クリックし、[ブラウザの選択]を選択してください(図14)。
![図14 コンテキストメニューからの[ブラウザの選択] 図14 コンテキストメニューからの[ブラウザの選択]](http://cz-cdn.shoeisha.jp/static/images/article/799/014.gif)

4.部分更新の確認
3.までの手順でサンプルは完成です。入力後に[F5]を押して実行、または[Ctrl]+[F5]を押して実行してみてください。UpdatePanelコントロール内にある[Button]ボタンをクリックした時に、Xml-HttpリクエストによりUpdatePanelコントロールの内側のみ非同期でポストバックを発生するため、ページ全体の更新を抑えられ、ブラウザの下部にプログレスバーが表示されることなくラベル上に「Hello,Ajax」と表示することができたと思います。今回はプロパティからの設定で作成しましたが、実際HTMLソース画面では次のようなソースが生成されています。
<form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /> <br /> <br /> <asp:Label ID="Label1" runat="server"></asp:Label> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" /> </Triggers> </asp:UpdatePanel> </div> </form>
インテリセンスが使えるという点とプロパティ名が分かりやすいためドキュメントを読まなくても利用できますが、ソースを直接入力して利用しようと考えている方は、しっかりとドキュメントを参照しておくことをおすすめします。
ちなみにUpdatePanelコントロールは、同一のWebページ内に複数配置することができます。複数のUpdatePanelコントロールを貼り付けて、それぞれのイベントトリガーを設定することで、発生したイベントに応じて、対応しているUpdatePanelコントロールの部分更新をさせることができます。
ここまでの段階で作成したUpdatePanelコントロール(内部のボタン、ラベルを含む)と同じ内容のUpdatePanelコントロールを作成して動作検証をしてみてください。Button2のコードでは、Labelに表示する文字を「Hello,Ajax」から「Hello,World」に変更することで違いを確認できます。
UpdatePanelコントロールを入れ子で配置する方法(サンプル2)
サンプル1までで基本的なUpdatePanelコントロールの使い方は学習できたと思います。それだけで利用することは十分に可能なのですが、UpdatePanelコントロールは応用的な使い方として、UpdatePanelコントロール内にUpdatePanelコントロールを配置する、入れ子としての使い方も可能になっています。そしてUpdatePanelコントロールには、この部分更新をより細かく設定するためのプロパティがあります。それはUpdateModeプロパティとChildrenAsTriggersプロパティです。
今回は1から作り直し、UpdatePanel1の中に入れ子のUpdatePanel2を作成します。そしてUpdatePanel1・UpdatePanel2内に「埋め込みコードブロック」を使い、ポストバックが起きた時の時間を表示させるように設定します。最後にUpdateModeプロパティとChildrenAsTriggersプロパティの動作を確認します。
1.コントロールを配置し、埋め込みコードブロックを入力する
今回のサンプルではサーバーサイドに直接的なコードを入力しません。しかし、ポストバックを起こすためにButtonコントロールを配置します(図16)。

UpdatePanel1の内部に同じ要領でUpdatePanel2とButton2を配置してください。その後UpdatePanel1とUpdatePanel2のフォームデザイナ画面で、埋め込みコードブロックを1つずつ入力します。今回は埋め込みコードブロック内に時間を表示させるために、以下のコードをフォームデザイナ内に埋め込みます。
<%=DateTime.Now.ToString() %>
入力場所は部分更新の確認を行うため、UpdatePanel1とUpdatePanel2の内側に入力をしてください。以下のコードを参考にしてください。
<asp:UpdatePanel ID="UpdatePanel1" runat="server" > <ContentTemplate> <asp:Button ID="Button1" runat="server" Text="Button" /> <br /> <%=DateTime.Now.ToString() %><br /> <asp:UpdatePanel ID="UpdatePanel2" runat="server"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="Button" /> <br /> <%=DateTime.Now.ToString() %> </ContentTemplate> </asp:UpdatePanel> </ContentTemplate> </asp:UpdatePanel>
入力後実行をすると、ボタンと実行時の時間が表示されます。ただし、この状態では、UpdatePanel1内のButton1とUpdatePanel2内のButton2のどちらが押されても表示される時間は同じです(図17)。これから、UpdatePanel2内のButton2を押した際にUpdatePanel2内の時間だけ更新させるように設定を変えます。

2.UpdatePanelコントロールのUpdateModeプロパティを設定する。
UpdateModeプロパティはデフォルトでAlwaysです。以下の全ての条件を満たした時、親UpdatePanelコントロールを含むコントロールを部分更新します。
- UpdatePanelコントロールの中にもう1つUpdatePanelコントロールが入っている
- 親と子UpdatePanelコントロールの
UpdateModeプロパティがAlways - 親UpdatePanelコントロール内に入れ子として存在している子UpdatePanelコントロールからのAsynchronous Postback(非同期ポストバック)が発生
一方、UpdateModeプロパティを親UpdatePanelコントロールでConditional、子UpdatePanelコントロールでAlways(AlwaysとConditionalしかありません)と設定した場合、子UpdatePanelコントロールで起きたイベントでは、子UpdatePanelコントロールのみの更新となります。ただし、もう1つ設定が必要なプロパティがあります。それはChildrenAsTriggersプロパティです。ChildrenAsTriggersプロパティがTrueに設定されていると(3.で後述します)、親UpdatePanelコントロールで起きた非同期ポストバックは子UpdatePanelコントロールでも部分更新されますが、子UpdatePanelコントロールで起きた非同期ポストバックは子UpdatePanelコントロールのみの部分更新が可能になります(図18)。
先ほどのサンプルのUpdatePanel2のUpdateModeプロパティをConditionalに設定します(図19:画像はUpdatPanel1と表示されていますが、実際はUpdatePanel2のプロパティをConditionalに設定してください)。
設定後実行して動作を確認してみると、UpdatePanel2のButton2をクリックした際にUpdatePanel2の時間だけが更新されることが分かります(図20)。しかし、UpdatePanel1のButton1をクリックした際には両方の時間が更新されます。UpdatePanelコントロールの入れ子は3重4重と行うことも可能なので、必要に応じて増やすことができます。

3.ChildrenAsTriggersプロパティについて
ChildrenAsTriggersプロパティはデフォルトでTrueです。このプロパティがTrueの時、UpdatePanelコントロール内に配置されているコントロールをトリガーにして部分更新を起こすことができます。また、2つのUpdatePanelコントロールがあり、2番目のパネルを部分更新する際に最初のパネルからのPostBackが必要になる時はChildrenAsTriggersプロパティをFalseに設定します。この時、UpdateModeのプロパティをAlwaysに設定していると、エラーが発生してしまう点に注意してください。







