2008が発売されました。AJAXが組み込まれていますので、別途インストールする必要がありません。AJAXの使い方はそのまま使えるはずです。AJAXを使わなかったものは、ゆうパックの料金を調べている最中に、「読み込み中...」と表示されていました。AJAXでこのような現在の状況を表示するには、UpdateProgressコントロールを使います。UpdateProgressコントロールの使い方は、非常に簡単です。前々号の「UpdatePanelを使う」のサンプルを改良して進行状況を表示するには、ページにUpdateProgressコントロールを追加し、その中(HTMLでは<ProgressTemplate>の中)に「読み込み中...」と記入するだけです。全体のコードを以下に示します。処理が終了してしまうと「読み込み中...」が一瞬で消えてしまいますので、ここではあえて時間がかかるように、DropDownListのSelectedIndexChangedイベントハンドラでThread.Sleepメソッドを呼び出しています。UpdateProgressのDisplayAfterプロパティを0にして、すぐに「読み込み中...」が表示されるようにしています。デフォルトは500となっており、500ミリ秒後に「読み込み中...」が表示されます。†ページ内にUpdatePanelが複数存在する場合は、基本的にはどのUpdatePanelが更新されてもUpdateProgressに現在の状況が表示されます。あるUpdatePanelが更新されたときだけUpdateProgressに状況を表示するには、UpdateProgressのAssociatedUpdatePanelIDプロパティを使用して、UpdatePanelと関連付けます。上記の例では、AssociatedUpdatePanelIDプロパティを"UpdatePanel1"としてUpdatePanel1と関連付けることができます。†UpdateProgressが置かれている部分は、HTMLでは<div>で囲まれます。UpdateProgressの中身が表示されていない時(はじめの状態)は、この<div>のdisplayスタイルがnoneですが、UpdateProgressの中身が表示される時は、JavaScriptでblockに変更されます。具体的には、上記の例では、UpdateProgress1の部分のHTMLは次のようになります。読み込み中...</div>ただしこのようになるのは、UpdateProgressのDynamicLayoutプロパティがTrueの場合です。これをFalseにすると、UpdateProgressの中身が表示されていない時の<div>のスタイルはdisplayがblockでvisibilityがhiddenとなり、UpdateProgressの中身が表示される時は、visibilityがvisibleに変更されます。読み込み中...</div>つまり、DynamicLayoutプロパティがTrueの場合は、UpdateProgressが表示されていない時はその場所を占有するものが何もない状態で、UpdateProgressが表示されるとその行が新に挿入されるようにして表示されます。よってこの場合は、UpdateProgressが表示されると、UpdateProgress以降のコンテンツは新に挿入された分だけ下に押し出されます。DynamicLayoutプロパティがFalseの場合は、UpdateProgressが表示されていない時でもその部分にUpdateProgressで表示する内容分のスペースが空いた状態になります。よってこの場合は、UpdateProgressが表示されても、UpdateProgress以降のコンテンツが動かされません。1.0では、前々号の「トリガーをUpdatePanelの外に出す」のサンプルのようにトリガーをUpdatePanelの外に出した場合は、UpdateProgressを追加しただけでは何も表示されません。AssociatedUpdatePanelIDプロパティを設定してもダメです。同様に、前号の「UpdatePanelに関連付けられていないコントロールで非同期ポストバックを行う」のようにRegisterAsyncPostBackControlメソッドを使った場合もうまくいきません。3.5でもうまくいきません。このようなケースで現在の状況を表示するには、JavaScriptを自分で書く必要があります。「JavaScriptを自分で書け」と言われても...と思われるかもしれませんが、メリットも多くあります。UpdateProgressコントロールを使わずに現在の状況を表示することができますので、より柔軟な表示が可能になります。†UpdateProgressコントロールを使わずに、自分で現在の状況を表示する場合、問題になるのは、いつ現在の状況を表示して、いつ消せばよいのかという点です。AJAXにはそれを解決する方法が用意されています。Library」というECMAScript(JavaScript)を基にしたクライアントプログラミングのフレームワークを使用します。Extensionsをインストールしていればインストールされますので、通常は問題ないでしょう。Libraryを単独でインストールすることもできます。LibraryにあるSys.WebForms.PageRequestManagerクラスのbeginRequestイベントで、いつ非同期ポストバックが開始されたかが分かりますので、このタイミングで現在の状況を表示させます。同じように、非同期ポストバックの終了はendRequestイベントで分かりますので、ここで現在の状況を非表示にします。このPageRequestManagerは、ScriptManagerコントロールのSupportsPartialRenderingプロパティがTrueの時に使用できます。デフォルトでTrueですので、通常は気にする必要はありません。ページにUpdatePanelコントロールが1つ以上あることも必要です。†それでは具体例を示します。ここではUpdateProgressコントロールを使わずに、結果を表示するLabelコントロールに"読み込み中..."と表示されるように先ほどのサンプルを改造します。先ほどのサンプルとの違いは、UpdateProgressコントロールを削除した点と、<script>を追加した点です。変更箇所は<html>内だけですので、以下に<html>内だけを示します。†JavaScriptのコードの説明をします。PageRequestManager.getInstanceメソッドにより、PageRequestManagerのインスタンスを作成します。非同期ポストバックが開始された時に発生するbeginRequestイベントのハンドラを追加します。beginRequestイベントハンドラ(InitializeRequestメソッド)では、まずトリガー(ポストバックを起こした要素)のIDを調べ、"PackageSizeList"かどうかを確認しています。あれば、結果を表示するLabelである"ResultLabel"というIDを持つ要素を取得し、その内容を"読み込み中..."に変更しています。"$get"というのは、Sys.UI.DomElement.getElementByIdメソッドのショートカットで、IDから要素を取得するためのメソッドです。JavaScriptを記述する位置ですが、必ずScriptManagerの後にしてください。ScriptManagerの前ではPageRequestManagerのインスタンスが作成されておらず、エラーになります。この例では非同期ポストバックが完了したときに何もしませんでした。非同期ポストバックが完了したときに、beginRequestで表示した現在の状況を消す必要がある場合は、endRequestイベントを使用します。endRequestイベントの使い方は、beginRequestイベントと同じです。上記の例ではページ内にJavaScriptを記述しましたが、外部ファイルにJavaScriptを記述してみましょう。src="progress.js"></script>とすることもできますが、ここではScriptManagerのScriptsプロパティを使用する方法を紹介します。†まずJavaScriptを外部ファイルに記述します。ここでは以下のようなコードを"progress.js"という名前で保存したとします。Sys.Application.notifyScriptLoaded();前のコードと比較すると、違いは2箇所あります。一つ目は、Sys.Application.loadイベントのハンドラ内でPageRequestManagerの作成を行っている点です。loadイベントはアプリケーション内のすべてのオブジェクトが作成、初期化された後に発生しますので、この時には確実にPageRequestManagerのインスタンスが作成されています。上記の例のようにApplication.add_loadを使う以外に、"pageLoad"という名前の関数を作成する方法があります。Libraryで予約された名前であり、"pageLoad"という名前の関数は、Application.loadイベントハンドラになるということになっています。pageLoadを使用した例を以下に示します。prm.add_initializeRequest(InitializeRequest);}2つ目の違いは、最後の行でSys.Application.notifyScriptLoadedメソッドを呼び出している点です。ScriptManagerのScriptsプロパティに登録されている外部JavaScriptでは、必ず最後でnotifyScriptLoadedを呼び出す必要があります。アセンブリに埋め込まれたスクリプトファイルでは、通常は、notifyScriptLoadedを呼び出してはいけません。これは、スクリプトを表すScriptReferenceオブジェクトのNotifyScriptLoadedプロパティがデフォルトでTrueであり、自動的にnotifyScriptLoadedが呼び出されるためです。スクリプトからnotifyScriptLoadedを呼び出したい場合は、NotifyScriptLoadedプロパティをFalseにします。†このように作成したJavaScriptファイルをScriptManagerのScriptsプロパティに追加するには、デザイナを使用した場合は、次のようにします。デザイナでScriptManagerを選択する。プロパティウィンドウの"Scripts"の右に表示される"..."ボタンをクリックして"ScriptReferenceコレクションエディタ"を表示する。"メンバ"の下の"追加"ボタンをクリックして、ScriptReferenceを追加する。プロパティ"の"Path"に"progress.js"と入力する。"OK"ボタンをクリックする。このようにして出来上がったコードは次のようになります。<html>内以外は初めの例と同じですので、<html>内だけを示します。