ASP.NET PageRequestManager 類別概觀
更新:2007 年 11 月
Microsoft AJAX Library 中的 PageRequestManager 類別負責管理瀏覽器中的網頁局部更新。當頁面包含 ScriptManager 控制項與一個或多個 UpdatePanel 控制項時,頁面會自動啟用網頁局部呈現功能。PageRequestManager 類別會公開 (Expose) 屬性、方法與事件,讓您可以使用用戶端指令碼來自訂網頁局部更新。PageRequestManager 類別會公開用戶端頁面事件模型,讓您可以以類似使用伺服器頁面事件模型的方式來使用。
這個主題包含:
案例
功能
背景
程式碼範例
HOW TO 和逐步解說主題
類別參考
案例
您可以用 ScriptManager 及 UpdatePanel Web 伺服器控制項來啟用網頁局部更新功能。網頁局部更新不需要用戶端指令碼。不過,您可以使用 PageRequestManager 類別與用戶端指令碼執行下列動作:
控制如何處理多個非同步回傳。預設行為是,最近的回傳具有較高的優先順序。PageRequestManager 類別可讓您為特定回傳指定優先順序,以及取消其他執行中的回傳。
提供視覺提示或其他通知,以標示由於最近的非同步回傳而更新或建立之頁面上的區域。這樣可改善使用者經驗,尤其是使用多個 UpdatePanel 控制項時。
在非同步回傳期間顯示狀態訊息。若處理回傳很耗時,您可能會想要顯示進度列指示器 (例如,動畫影像)。您也可以提供選項,讓使用者可以取消回傳。
提供網頁局部更新的自訂錯誤訊息處理。在非同步回傳期間若發生未預期的錯誤,您可以在用戶端指令碼中處理錯誤。
存取用於非同步回傳的基礎要求與回應物件。
功能
Microsoft AJAX Library 中的網頁局部更新功能包括:
用戶端頁面生命週期事件,這些事件是在網頁局部更新期間的關鍵時間引發。
在非同步回傳期間刪除、更新或建立之 UpdatePanel 控制項的相關資訊。
可讓您在用戶端指令碼中使用的屬性與方法,以判斷是否正以非同步回傳方式處理頁面。您也可以使用這些方法來停止正在執行的非同步回傳,或取消新的回傳。
傳送至未參與網頁局部更新之控制項的伺服器資料相關資訊。
背景
在由非同步回傳起始的網頁局部更新期間,PageRequestManager 類別會協調在瀏覽器中逐步更新頁面內容的方式。UpdatePanel 伺服器控制項與 PageRequestManager 用戶端類別會將多數網頁局部更新複雜度抽象化。當您使用用戶端指令碼與 PageRequestManager 類別的成員時,可以自訂瀏覽器中的網頁局部更新行為。
網頁局部更新事件處理
在回傳與非同步回傳頁面處理期間,您可以處理瀏覽器文件物件模型 (DOM) 事件,以執行自訂指令碼。例如,您可以在瀏覽器載入或卸載頁面時執行指令碼。
不過,這些 DOM 事件無法讓您存取所有相關資訊,也無法讓您在非同步回傳與網頁局部更新期間控制行為。因此,PageRequestManager 類別會公開 (Expose) 下列事件,讓您自訂網頁局部更新:
如需這些事件的詳細資訊,請參閱使用 PageRequestManager 事件。
程式碼範例
下列範例顯示頁面在非同步回傳之後更新時,如何使用 PageRequestManager 類別的 pageLoaded 事件讓 UpdatePanel 控制項以動畫方式顯示。在此範例中,使用者可以選取日期並在表單中輸入電子郵件地址,以產生票證要求。發生非同步回傳時 (由 UpdatePanel 控制項外部的連結所觸發),會以動畫方式簡短地顯示面板,以通知使用者日期值已輸入文字方塊。頁面包含快顯視窗,它會顯示 Calendar 控制項。使用控制項的 Visible 屬性即可決定要顯示或隱藏行事曆。顯示或隱藏行事曆,或選取日期時,不需要重新整理整個頁面,因為 Calendar 控制項位於 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 >
Protected Sub ChosenDate_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim dt As New DateTime()
DateTime.TryParse(ChosenDate.Text, dt)
CalendarPicker.SelectedDate = dt
CalendarPicker.VisibleDate = dt
End Sub
Protected Sub Close_Click(ByVal sender As Object, ByVal e As EventArgs)
SetDateSelectionAndVisible()
End Sub
Protected Sub ShowDatePickerPopOut_Click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
DatePickerPopOut.Visible = Not (DatePickerPopOut.Visible)
End Sub
Protected Sub CalendarPicker_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs)
SetDateSelectionAndVisible()
End Sub
Private Sub SetDateSelectionAndVisible()
If (CalendarPicker.SelectedDates.Count <> 0) Then
ChosenDate.Text = CalendarPicker.SelectedDate.ToShortDateString()
End If
DatePickerPopOut.Visible = False
End Sub
Protected Sub SubmitButton_Click(ByVal sender As Object, ByVal e As EventArgs)
If (Page.IsValid) Then
MessageLabel.Text = "An email with availability was sent."
Else
MessageLabel.Text = ""
End If
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
CompareValidatorDate.ValueToCompare = DateTime.Today.ToShortDateString()
ExtraShow1.Text = DateTime.Today.AddDays(10.0).ToShortDateString()
ExtraShow2.Text = DateTime.Today.AddDays(11.0).ToShortDateString()
End Sub
Protected Sub ExtraShow_Click(ByVal sender As Object, ByVal e As EventArgs)
ChosenDate.Text = CType(sender, LinkButton).Text
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
<title>Calendar Example</title>
<style type="text/css">
body {
font-family: Tahoma;
}
.PopUpCalendarStyle
{
background-color:lightblue;
position:absolute;
visibility:show;
margin: 15px 0px 0px 10px;
z-index:99;
border: solid 2px black;
}
.UpdatePanelContainer
{
width: 260px;
height:110px;
}
</style>
</head>
<body>
<form id="form1" >
<asp:ScriptManager ID="ScriptManager1" />
<script type="text/javascript">
Type.registerNamespace("ScriptLibrary");
ScriptLibrary.BorderAnimation = function(color, duration) {
this._color = color;
this._duration = duration;
}
ScriptLibrary.BorderAnimation.prototype = {
animatePanel: function(panelElement) {
var s = panelElement.style;
s.borderWidth = '1px';
s.borderColor = this._color;
s.borderStyle = 'solid';
window.setTimeout(
function() {{ s.borderWidth = 0; }},
this._duration
);
}
}
ScriptLibrary.BorderAnimation.registerClass('ScriptLibrary.BorderAnimation', null);
var panelUpdatedAnimation = new ScriptLibrary.BorderAnimation('blue', 1000);
var postbackElement;
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
function beginRequest(sender, args) {
postbackElement = args.get_postBackElement();
}
function pageLoaded(sender, args) {
var updatedPanels = args.get_panelsUpdated();
if (typeof(postbackElement) === "undefined") {
return;
}
else if (postbackElement.id.toLowerCase().indexOf('extrashow') > -1) {
for (i=0; i < updatedPanels.length; i++) {
panelUpdatedAnimation.animatePanel(updatedPanels[i]);
}
}
}
</script>
<h1>Tickets</h1>
<p>
<strong>Latest News</strong> Due to overwhelming response, we
have added two extra shows on:
<asp:LinkButton ID="ExtraShow1" OnClick="ExtraShow_Click" />
and
<asp:LinkButton ID="ExtraShow2" OnClick="ExtraShow_Click" />.
Don't forget curtain time is at 7:00pm sharp. No late arrivals.
</p>
<hr />
<div class="UpdatePanelContainer">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ExtraShow1" />
<asp:AsyncPostBackTrigger ControlID="ExtraShow2" />
</Triggers>
<ContentTemplate>
<fieldset >
<legend>Check Ticket Availability</legend>Date
<asp:TextBox ID="ChosenDate" OnTextChanged="ChosenDate_TextChanged" />
<asp:ImageButton ID="ShowDatePickerPopOut" OnClick="ShowDatePickerPopOut_Click"
ImageUrl="../images/calendar.gif" AlternateText="Choose a date."
Height="20px" Width="20px" />
<asp:Panel ID="DatePickerPopOut" CssClass="PopUpCalendarStyle"
Visible="false" >
<asp:Calendar ID="CalendarPicker" OnSelectionChanged="CalendarPicker_SelectionChanged">
</asp:Calendar>
<br />
<asp:LinkButton ID="CloseDatePickerPopOut" Font-Size="small"
OnClick="Close_Click" ToolTip="Close Pop out">
Close
</asp:LinkButton>
</asp:Panel>
<br />
Email
<asp:TextBox ID="EmailTextBox" />
<br />
<br />
<asp:Button ID="SubmitButton" Text="Check" ValidationGroup="RequiredFields"
OnClick="SubmitButton_Click" />
<br />
<asp:CompareValidator ID="CompareValidatorDate"
ControlToValidate="ChosenDate" ErrorMessage="Choose a date in the future."
Operator="GreaterThanEqual" Type="Date" Display="None" ValidationGroup="RequiredFields" EnableClientScript="False"></asp:CompareValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorDate"
ControlToValidate="ChosenDate" Display="None" ErrorMessage="Date is required."
ValidationGroup="RequiredFields" EnableClientScript="False"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidatorEmail"
ControlToValidate="EmailTextBox" Display="None"
ValidationGroup="RequiredFields" ErrorMessage="The email was not correctly formatted."
ValidationExpression="^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$" EnableClientScript="False"></asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorEmail"
ValidationGroup="RequiredFields" ControlToValidate="EmailTextBox"
Display="None" ErrorMessage="Email is required." EnableClientScript="False"></asp:RequiredFieldValidator><br />
<asp:ValidationSummary ID="ValidationSummary1"
ValidationGroup="RequiredFields" EnableClientScript="False" />
<asp:Label ID="MessageLabel" />
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
</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 >
protected void ChosenDate_TextChanged(object sender, EventArgs e)
{
DateTime dt = new DateTime();
DateTime.TryParse(ChosenDate.Text, out dt);
CalendarPicker.SelectedDate = dt;
CalendarPicker.VisibleDate = dt;
}
protected void Close_Click(object sender, EventArgs e)
{
SetDateSelectionAndVisible();
}
protected void ShowDatePickerPopOut_Click(object sender, ImageClickEventArgs e)
{
DatePickerPopOut.Visible = !DatePickerPopOut.Visible;
}
protected void CalendarPicker_SelectionChanged(object sender, EventArgs e)
{
SetDateSelectionAndVisible();
}
private void SetDateSelectionAndVisible()
{
if (CalendarPicker.SelectedDates.Count != 0)
ChosenDate.Text = CalendarPicker.SelectedDate.ToShortDateString();
DatePickerPopOut.Visible = false;
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
MessageLabel.Text = "An email with availability was sent.";
}
else
{
MessageLabel.Text = "";
}
}
protected void Page_Load(object sender, EventArgs e)
{
CompareValidatorDate.ValueToCompare = DateTime.Today.ToShortDateString();
ExtraShow1.Text = DateTime.Today.AddDays(10.0).ToShortDateString();
ExtraShow2.Text = DateTime.Today.AddDays(11.0).ToShortDateString();
}
protected void ExtraShow_Click(object sender, EventArgs e)
{
ChosenDate.Text = ((LinkButton)sender).Text;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" >
<title>Calendar Example</title>
<style type="text/css">
body {
font-family: Tahoma;
}
.PopUpCalendarStyle
{
background-color:lightblue;
position:absolute;
visibility:show;
margin: 15px 0px 0px 10px;
z-index:99;
border: solid 2px black;
}
.UpdatePanelContainer
{
width: 260px;
height:110px;
}
</style>
</head>
<body>
<form id="form1" >
<asp:ScriptManager ID="ScriptManager1" />
<script type="text/javascript">
Type.registerNamespace("ScriptLibrary");
ScriptLibrary.BorderAnimation = function(color, duration) {
this._color = color;
this._duration = duration;
}
ScriptLibrary.BorderAnimation.prototype = {
animatePanel: function(panelElement) {
var s = panelElement.style;
s.borderWidth = '1px';
s.borderColor = this._color;
s.borderStyle = 'solid';
window.setTimeout(
function() {{ s.borderWidth = 0; }},
this._duration
);
}
}
ScriptLibrary.BorderAnimation.registerClass('ScriptLibrary.BorderAnimation', null);
var panelUpdatedAnimation = new ScriptLibrary.BorderAnimation('blue', 1000);
var postbackElement;
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
function beginRequest(sender, args) {
postbackElement = args.get_postBackElement();
}
function pageLoaded(sender, args) {
var updatedPanels = args.get_panelsUpdated();
if (typeof(postbackElement) === "undefined") {
return;
}
else if (postbackElement.id.toLowerCase().indexOf('extrashow') > -1) {
for (i=0; i < updatedPanels.length; i++) {
panelUpdatedAnimation.animatePanel(updatedPanels[i]);
}
}
}
</script>
<h1>Tickets</h1>
<p>
<strong>Latest News</strong> Due to overwhelming response, we
have added two extra shows on:
<asp:LinkButton ID="ExtraShow1" OnClick="ExtraShow_Click" />
and
<asp:LinkButton ID="ExtraShow2" OnClick="ExtraShow_Click" />.
Don't forget curtain time is at 7:00pm sharp. No late arrivals.
</p>
<hr />
<div class="UpdatePanelContainer">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ExtraShow1" />
<asp:AsyncPostBackTrigger ControlID="ExtraShow2" />
</Triggers>
<ContentTemplate>
<fieldset>
<legend>Check Ticket Availability</legend>Date
<asp:TextBox ID="ChosenDate" OnTextChanged="ChosenDate_TextChanged" />
<asp:ImageButton ID="ShowDatePickerPopOut" OnClick="ShowDatePickerPopOut_Click"
ImageUrl="../images/calendar.gif" AlternateText="Choose a date."
Height="20px" Width="20px" />
<asp:Panel ID="DatePickerPopOut" CssClass="PopUpCalendarStyle"
Visible="false" >
<asp:Calendar ID="CalendarPicker" OnSelectionChanged="CalendarPicker_SelectionChanged">
</asp:Calendar>
<br />
<asp:LinkButton ID="CloseDatePickerPopOut" Font-Size="small"
OnClick="Close_Click" ToolTip="Close Pop out">
Close
</asp:LinkButton>
</asp:Panel>
<br />
Email
<asp:TextBox ID="EmailTextBox" />
<br />
<br />
<asp:Button ID="SubmitButton" Text="Check" ValidationGroup="RequiredFields"
OnClick="SubmitButton_Click" />
<br />
<asp:CompareValidator ID="CompareValidatorDate"
ControlToValidate="ChosenDate" ErrorMessage="Choose a date in the future."
Operator="GreaterThanEqual" Type="Date" Display="None" ValidationGroup="RequiredFields" EnableClientScript="False"></asp:CompareValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorDate"
ControlToValidate="ChosenDate" Display="None" ErrorMessage="Date is required."
ValidationGroup="RequiredFields" EnableClientScript="False"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidatorEmail"
ControlToValidate="EmailTextBox" Display="None"
ValidationGroup="RequiredFields" ErrorMessage="The email was not correctly formatted."
ValidationExpression="^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$" EnableClientScript="False"></asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorEmail"
ValidationGroup="RequiredFields" ControlToValidate="EmailTextBox"
Display="None" ErrorMessage="Email is required." EnableClientScript="False"></asp:RequiredFieldValidator><br />
<asp:ValidationSummary ID="ValidationSummary1"
ValidationGroup="RequiredFields" EnableClientScript="False" />
<asp:Label ID="MessageLabel" />
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
HOW TO 和逐步解說主題
類別參考
下表列出與 PageRequestManager 類別相關的類別。
Class |
描述 |
---|---|
管理用戶端網頁局部更新並公開自訂用戶端指令碼的成員。 |
|
提供 initializeRequest 事件的事件資料,會在開始執行非同步要求前引發此事件。 |
|
提供 beginRequest 事件的事件資料,開始非同步回傳之後、傳送回傳到伺服器之前,會引發此事件。 |
|
提供 pageLoading 事件的事件資料,收到非同步回傳的回應之後、頁面上的任何內容更新之前,會引發此事件。若回傳停止或處理期間伺服器上擲回未處理的例外狀況,則不會引發此事件。 |
|
提供 pageLoaded 事件的事件資料,重新整理頁面上的所有內容 (不論是同步回傳或非同步回傳的結果) 之後,會引發此事件。若回傳停止或處理期間伺服器上擲回未處理的例外狀況,則不會引發此事件。 |
|
提供 endRequest 事件的事件資料,完成非同步回傳之後會引發此事件。 |