クライアント スクリプト内の UpdateProgress コントロールのプログラミング
更新 : 2007 年 11 月
このチュートリアルでは、ECMAScript (JavaScript) コードを記述して、クライアント動作を含む UpdateProgress コントロールを拡張します。コードでは、Microsoft AJAX Library の一部である PageRequestManager クラスを使用します。UpdateProgress コントロールに、ユーザーが非同期ポストバックをキャンセルできるボタンを追加します。このタスクの一部として、クライアント スクリプトを使用して進行状況メッセージを表示または非表示にします。
このトピックでは、UpdateProgress コントロールについて理解していることを前提としています。理解していない場合は、「UpdateProgress コントロールの概要」を参照してください。
前提条件
独自の開発環境でこの手順を実装するための要件は次のとおりです。
Microsoft Visual Studio 2005 または Visual Web Developer Express Edition。
AJAX 対応の ASP.NET Web サイト。
クライアント スクリプトで非同期ポストバックをキャンセルするには
新しい ASP.NET Web ページを作成し、デザイン ビューに切り替えます。
ツールボックスの [AJAX Extensions] タブで、ScriptManager、UpdatePanel、UpdateProgress の各コントロールをダブルクリックして、各コントロールのインスタンスをページに追加します。
ツールボックスの [標準] タブで、Label コントロールを UpdatePanel コントロールに追加し、ラベルの Text プロパティを "Panel Rendered" に設定します。
Button コントロールを UpdatePanel コントロールに追加し、その Text プロパティを "Refresh" に設定します。
UpdateProgress コントロール内に、"Processing…" というテキストを追加します。
ツールボックスの [HTML] タブで、HtmlButton コントロールを UpdateProgress コントロールに追加し、その Value 属性を "Cancel" に設定します。
[Refresh] ボタンをダブルクリックして、その Click イベントのイベント ハンドラを追加します。
次のコードを Click ハンドラに追加します。これにより、3 秒の遅延が人為的に作成され、ラベルが現在のサーバー時刻に設定されます。
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Sub
protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); }
メモ : Click イベントのハンドラは、このチュートリアルに意図的に遅延を導入します。実際には、ユーザーが遅延を導入することはありません。サーバー トラフィックや、処理に時間がかかるサーバー コード (長時間実行するデータベース クエリなど) によって遅延が発生します。
<asp:ScriptManager> 要素の下に次のスクリプトを追加します。
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script>
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script>
スクリプトは、PageRequestManager クラスの現在のインスタンスを取得します。次に、abortPostBack メソッドを呼び出す関数を作成して、非同期ポストバックを停止します。
HtmlButton コントロールの onclick 属性を CancelAsyncPostBack に設定します。これは、前の手順で作成したハンドラの名前です。
<input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" />
<input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" />
<head> 要素に次のスタイル ブロックを追加します。
<style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style>
<style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style>
スタイル設定により、ブラウザ ウィンドウの左下隅に UpdateProgress コントロールが表示されるように構成されます。
変更内容を保存し、Ctrl キーを押しながら F5 キーを押して、ブラウザでページを表示します。
[最新の情報に更新] をクリックします。
少し待つと、進行状況メッセージが表示されます。UpdatePanel コントロール内のメッセージが時刻の表示に変わるように、部分ページ更新を終了させます。
メモ : DisplayAfter プロパティを設定することで、遅延の時間を構成できます。既定値は、500 ミリ秒です。
もう一度 [Refresh] をクリックした後、すぐに [Cancel] をクリックして、部分ページ更新を停止します。
UpdatePanel 内の時刻は更新されないことに注意してください。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"/> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"/> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button2" runat="server" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </form> </body> </html>
クライアント スクリプトを使用した更新の進行状況の表示
次のシナリオでは、UpdateProgress コントロールは自動的に表示されません。
UpdateProgress コントロールは特定の更新パネルに関連付けられますが、非同期ポストバックは、その更新パネル内にないコントロールから発生します。
UpdateProgress コントロールは UpdatePanel コントロールに関連付けられていません。また、非同期ポストバックは、UpdatePanel 内になく、トリガではないコントロールからは発生しません。たとえば、更新はコード内で行われます。
非同期ポストバックが、関連付けられた UpdatePanel コントロール内から発生しない場合に、UpdateProgress コントロールを表示する手順を次に示します。この手順では、このチュートリアルの最初の部分が完了していることを前提としています。
UpdateProgress コントロールをプログラムで表示するには
以前に作成したページで、デザイン ビューに切り替えます。
[プロパティ] ウィンドウで UpdateProgress コントロールを選択し、その AssociatedUpdatePanelID プロパティを "UpdatePanel1" に設定します。
UpdatePanel コントロールと UpdateProgress コントロールの外側に Button コントロールを追加します。
ボタンの Text プロパティを "Trigger" に設定し、ID を "Panel1Trigger" に設定します。
UpdatePanel コントロールを選択し、[プロパティ] ウィンドウで、Triggers プロパティのボックスの省略記号 (…) をクリックします。
[UpdatePanelTrigger コレクション エディタ] ダイアログ ボックスが表示されます。
AsyncPostBackTrigger オブジェクトを作成し、その ControlID プロパティを "Panel1Trigger" に設定します。
[OK] をクリックしてコレクション エディタを閉じます。
[Trigger] ボタンをダブルクリックして、その Click イベントのイベント ハンドラを追加します。
次のコードを Click ハンドラに追加します。これにより、3 秒の遅延が人為的に作成されます。その後、サーバー時刻と、トリガによってポストバックが発生したことを示すメッセージが表示されます。
Protected Sub Panel1Trigger_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() & " - trigger" End Sub
protected void Panel1Trigger_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString() + " - trigger"; }
ソース ビューで、ページ内に既に存在する <script> ブロックの下に次のクライアント スクリプトを追加します。
prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } }
prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } }
このスクリプトは、次の処理を行います。
PageRequestManager クラスの initializeRequest イベントのハンドラを定義します。ハンドラ コードにより、既に進行中の非同期ポストバックがキャンセルされます。それ以外の場合、ポストバックが Panel1Trigger<div> 要素で発生すると、コードは UpdateProgress テンプレートを表示します。
PageRequestManager クラスの endRequest イベントのハンドラを定義します。ポストバックが Panel1Trigger<div> 要素で発生した場合、ハンドラ コードはプログレス コントロールを非表示にします。
完全なスクリプト ブロックの例を次に示します。
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script>
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script>
変更内容を保存し、Ctrl キーを押しながら F5 キーを押して、ブラウザでページを表示します。
[Refresh] ボタンをクリックします。
少し待つと、進行状況メッセージが表示されます。UpdatePanel コントロール内のメッセージに時刻が表示されるように、部分ページ更新を終了させます。
[Trigger] ボタンをクリックします。
進行状況メッセージが表示されます。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Sub Protected Sub Panel1Trigger_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() & " - trigger" End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" runat="server" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); } protected void Panel1Trigger_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString() + " - trigger"; } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" runat="server" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html>
レビュー
このチュートリアルでは、JavaScript コードを記述して UpdateProgress コントロールの動作を拡張する方法について説明しました。PageRequestManager クラスのイベントとメソッドを使用すると、非同期ポストバックをキャンセルし、プログラムによって UpdateProgress コントロールを表示および非表示にできます。