初學 ASP.NET AJAX (三):使用 UpdatePanel

1 概述
ASP.NET UpdatePanel 控件能讓你創建豐富的、以客戶爲中心的 Web 應用程序。使用 UpdatePanel 控件,可以刷新選擇的頁面部分而不是使用回發來刷新整個頁面,這就像是執行了一個局部頁面更新一樣。包含一個 ScriptManager 和一個或多個 UpdatePanel 的 Web 頁面會自動加入局部頁面更新,而不需要定製客戶端代碼。

1.1 場景
UpdatePanel 是一個服務器控件,可以幫助你開發使用複雜客戶端行爲的 Web 頁面,使 Web 頁面呈現更多的交互給用戶。服務器和客戶端之間協調以僅更新指定的頁面部分通常需要很深的 ECMAScript(Javascript)知識。然而,通過使用UpdatePanel 控件,可以不用編寫任何客戶端腳本就可以給頁面加入局部頁面更新。如果你願意,可以添加定製的客戶端腳本以增強客戶端用戶體驗。在使用 UpdatePanel 控件時,頁面行爲是獨立於瀏覽器的,並且潛在的減少了客戶端和服務器的數據傳輸量。

1.2 背景
UpdatePanel 的工作是指定無須刷新整個頁面就可以更新的區域,這個過程由 ScriptManager 服務器控件和客戶端 PageRequestManager 類進行協調。當局部更新可用時,控件可以異步的發送到服務器。異步回發的行爲和常規回發一樣,結果服務器頁面會執行完整的頁面和控件生命週期。然而,使用異步回發,頁面更新僅限於封閉在 UpdatePanel 控件中標記爲更新的頁面區域。服務器僅爲受影響的元素髮送 HTML 標記到瀏覽器。在瀏覽器中,客戶端 PageRequestManager 類執行文檔對象模型 ( DOM ) 操作用更新的標記替換得已有的 HTML 。下面的圖例展示了頁面的第一次加載,和後來的刷新 UpdatePanel 控件的內容的異步回發。


2 UpdatePanel 的使用
UpdatePanel 的基本使用方法非常簡單,向頁面中添加一個 SciprtManager 控件和一個或多個 UpdatePanel 控件,再把要局部更新的頁面元素和觸發更新的控件放到 UpdatePanel 控件的 ContentTemplate 屬性中即可。如下列代碼所示,在其中添加了一個 Button 控件:

<asp:UpdatePanelID="UpdatePanel1"
        UpdateMode="Conditional"
        runat="server">
    <ContentTemplate>
        <asp:Button ID="Button1"
            Text="RefreshPanel"
            runat="server"/>
    </ContentTemplate>
</asp:UpdatePanel>

要使用 UpdatePanel 控件可用,必須設置 ScriptManager 的 EnablePartialRendering  屬性爲 true 。
UpdatePanel 控件可以輸出爲 <div> 元素或 <span> 元素,以在頁面中形成一個塊或內聯的區域,可以設置其 RenderMode 屬性爲 Block ( 默認,<div>)或 Inline ( <span> ) 來指定。

2.1 指定 UpdatePanel 的內容
可以使用 ContentTemplate 屬性以聲明的方式或者在設計器中添加內容到 UpdatePanel 控件中。在標記中,這個屬性顯示爲 <ContentTemplate> 元素。如果要以編程的方式添加內容,可以使用 ContentTemplateContainer 屬性。
包含一個或多個 UpdatePanel 控件的頁面在第一次輸出時,所有 UpdatePanel 控件中的內容都會被輸出並被髮送到瀏覽器。在後來的異步更新中,單個 UpdatePanel 控件中的內容可能會被更新。更新依賴於面板的設置、導致回發的元素以及指定給每個面板的代碼。

2.2 指定 UpdatePanel 的觸發器
默認情況下,UpdatePanel 控件中的任何控件回發都將導致異步回發並刷新面板的內容。然而,也可以配置頁面中且不在面板中的其他控件來刷新 UpdatePanel 控件。可以爲 UpdatePanel 控件定義一個觸發器來完成此目的。觸發器是指定哪個回發控件和事件來導致面板的更新的綁定。當觸發器控件指定的事件觸發時(如一個按鈕的 Click 事件),更新面板將被刷新。
下列示例展示瞭如何添加一個觸發器到 UpdatePanel 面板中去。

<asp:Button ID="Button1"
         Text="Refresh Panel"
          runat="server" />
<asp:ScriptManager ID="ScriptManager1"
          runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"   UpdateMode="Conditional" runat="server">
         <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Button1" />
        </Triggers>
       <ContentTemplate>
              <fieldset>
                  <legend>UpdatePanel 內容</legend>
                  <%=DateTime.Now.ToString() %>
              </fieldset>
       </ContentTemplate>
</asp:UpdatePanel>

 觸發器由在 UpdatePanel 控件的 <Triggers> 元素中的 <asp:AsyncPostBackTrigger> 元素定義。(如果是在 Visual Studio 中編輯頁面,就可以在 UpdatePanel 的屬性面板中單擊 Triggers 屬性後面的省略號按鈕打開一個 UpdatePanelTrigger 集合編輯器對話框來創建觸發器。)觸發器必要的屬性是 ControlID ,用它來指定可以導致面板更新的控件的 ID 。
有上例中,雖然按鈕沒有聲明在面板中,但是由於在面板中指定了它爲觸發器,所以當按鈕事件觸發時,會產生其被包含中面板中同樣的結果,即面板被更新。
觸發器控件的事件是可選的,如果沒有指定事件,觸發器將使用控件的默認事件。例如,對於 Button 控件,默認事件就是 Click 事件。

2.3 在母版頁中使用 UpdatePanel
要在母版頁中使用 UpdatePanel 控件,必須確定如何使用 ScriptManager 控件。如果在母版頁面中放置了一個 ScriptManater 控件,則 ScriptManager 控件可以在所有的內容面中起作用。(如果要在內容頁中聲明腳本或服務,可以在頁面中添加一個 ScriptManagerProxy,它具有和 ScriptManager 差不多一樣的屬性和方法。)
如果在母版頁中沒有包含 ScriptManager 控件,就必須在包含 UpdatePanel 控件的每個內容頁是都要放置一個 ScriptManager 控件,設計的選擇依賴於在應用程序中將如何管理客戶端腳本。
如果在母版頁中包含了 ScriptManager 控件,而在某個內容頁中又不打算使用局部頁面輸出的功能時,必須用程序設置內容中的 ScriptManager 控件的 EnablePartialRendering 爲 false  。

2.4 使用嵌套的 UpdatePanel 控件
UpdatePanel 控件可以嵌套使用,如果父面板被刷新,則所有嵌套的面板也都會被刷新。
下列代碼展示瞭如何在一個 UpdatePanel 控件中定義另一個 UpdatePanel 控件。

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>UpdatePanelUpdateMode 示例</title>
    <style type="text/css">
    div.NestedPanel
    {
      position: relative;
      margin: 2% 5% 2% 5%;
    }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="ScriptManager"
                               runat="server" />
            <asp:UpdatePanel ID="OuterPanel"
                             UpdateMode="Conditional"
                             runat="server">
                <ContentTemplate>
                    <div>
                        <fieldset>
                            <legend>外層 Panel </legend>
                            <br />
                            <asp:Button ID="OPButton1"
                                        Text="外層面板按鈕"
                                        runat="server" />
                            <br />
                            最後更新在:
                            <%= DateTime.Now.ToString() %>
                            <br />
                            <br />
                            <asp:UpdatePanel ID="NestedPanel1"
                                               UpdateMode="Conditional"
                                               runat="server">
                                <ContentTemplate>
                                    <div class="NestedPanel">
                                        <fieldset>
                                            <legend>嵌套面板</legend>
                                            <br />
                                            最後更新在:
                                            <%= DateTime.Now.ToString() %>
                                            <br />
                                            <asp:Button ID="NPButton1"
                                                        Text="嵌套面板按鈕"
                                                        runat="server" />
                                        </fieldset>
                                    </div>
                                </ContentTemplate>
                            </asp:UpdatePanel>
                        </fieldset>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
    </form>
</body>
</html>

2.5 用程序創建 UpdatePanel 控件
要用程序添加一個 UpdatePanel 控件到頁面中,可以先創建一個新的 UpdatePanel 實例,然後使用它的 ContentTemplateContainer 屬性的 Add( Control ) 方法來添加其他控件。不能直接使用 ContentTemplate  屬性來添加控件。
如果 UpdatePanel 控件是程序添加的,只有來自同樣命名容器如 UpdatePanel 控件中控件的回發纔可以被使用爲面板的觸發器。
下列代碼演示瞭如何用程序添加 UpdatePanel 控件。

<%@ 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 Page_Load(object sender, EventArgs e)
    {
        UpdatePanel up1 = new UpdatePanel();
        up1.ID = "UpdatePanel1";
        up1.UpdateMode = UpdatePanelUpdateMode.Conditional;
        Button button1 = new Button();
        button1.ID = "Button1";
        button1.Text = "Submit";
        button1.Click += new EventHandler(Button_Click);
        Label label1 = new Label();
        label1.ID = "Label1";
        label1.Text = "A full page postback occurred.";
        up1.ContentTemplateContainer.Controls.Add(button1);
        up1.ContentTemplateContainer.Controls.Add(label1);
        Page.Form.Controls.Add(up1);

    }
    protected void Button_Click(object sender, EventArgs e)
    {
        ((Label)Page.FindControl("Label1")).Text = "Panel refreshed at " +
            DateTime.Now.ToString();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>UpdatePanel Added Programmatically Example</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="TheScriptManager"
                               runat="server" />
        </div>
    </form>
</body>
</html>

3 UpdatePanel 的關鍵屬性
ChildrenAsTriggers:
指示來自 UpdatePanel 控件的直接子控件的回發是否更新面板的內容。設置爲 true 時更新,否則不更新,默認爲 true 。如果此屬性設置爲 false ,UpdatePanel 控件的 UpdateMode 就必須設置爲 Conditional ,否則會拋出 InvalidOperationException 異常。
UpdateMode:
指示什麼時候需要更新面板。當一個UpdatePanel 控件沒有包含在另一個 UpatePanel 控件中時,面板的更新是根據 UpdateMode 、ChildrenAsTriggers 屬性的設置,以及觸發器的集合來進行的。當一個 UpdatePanel 控件在另一個 UpdatePanel 控件內部時,子面板會自動在父面板更新時更新。
UpdatePanel 控件的內容在下列情形下會更新:
  • 如果 UpdateMode 屬性設置爲 Alwarys 時,UpdatePanel 控件中的內容會在源自頁面上任何地方的每個回發時更新。這包括由包含在其他 UpdatePanel 控件中的控件的回發和沒有在 UpdatePanel 控件中的回發。
  • 如果 UpdatePanel 控件嵌套在另一個 UpdatePanel 控件中時,父面板更新時它也會被更新。
  • 如果 UpdateMode 屬性被設置爲 Conditional 時,且出現下列條件之一時:
    • 顯式調用 UpdatePanel 控件的 Update() 方法。
    • 由 UpdatePanel 控件中的 Triggers 屬性定義的觸發器控件引起的回送。在這種情況下,控件會顯式的觸發面板內容的更新。定義爲觸發器的控件可以在 UpdatePanel 控件的內部也可以在其外部。
    • ChildrenAsTriggers 屬性設置爲 true ,並且是由 UpdatePanel 控件中的子控件導致的回發。在嵌套的 UpdatePanel 控件中的子控件不會引起外層 UpdatePanel 控件的更新,除非顯示的定義爲觸發器。
4 總結
由以上內容可以看出,使用 UpdatePanel 控件可以方便的幫助大家開發出具有 AJAX 特性的 ASP.NET 應用程序來。當然,它也不是萬能的,過度的使用會引起一定的性能開銷,同時它還與現在的部分 ASP.NET 控件不兼容,如 TreeView、Menu,以及 WebParts 控件等。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章