第3章ASP.NET AJAX入門篇
3.1 動態顯示的控件
你是否曾因Calendar控件的Postback動作所導致的網頁刷新而煩惱,轉而尋找其他不會導致網頁刷新的JavaScript日期選取控件呢?有了UpdatePanel控件的部分刷新技術之后,只要將Calendar控件放置于UpdatePanel控件中,Calendar控件的選取日期動作就不會再觸發整個網頁的刷新了!更甚之,利用UpdatePanel控件的嵌套UpdatePanel設計,我們可以輕易做出常在Windows Form上看到的下拉菜單,何謂下拉菜單呢?這是一種類似DropDownList的控件,只是在Windows Form上的下拉菜單所顯示的內容包羅萬象,從最常見的在下拉框中顯示一個Grid,讓使用者挑選所要的客戶或產品編號,到在下拉框中顯示圖形都有。在以往,這種UI效果并不容易在網頁上呈現出來。以Grid來說,以往要在網頁上呈現時,得將GridView控件及其要顯示的數據事先準備好,以不可視的狀態,也就是利用CSS的style.visibility將GridView控件先設為不可視,在使用者點擊下拉框按鈕后,再用JavaScript將GridView控件設為可視。這樣做最大的問題是GridView控件與數據于網頁加載時就已經存在,而且無法做分頁動作,可想而知當數據量大時,此網頁的加載速度會有多慢了。若改用UpdatePanel控件來做同樣動作的話,除了不需觸碰到JavaScript外,也可以讓拉出來的Grid擁有分頁的能力,完全解決了以往于網頁上制做下拉菜單的困難,真這么神奇嗎?請依以下步驟來創建一個Web Site。
1. 創建一個AJAX-Enabled的Web Site,命名為AjaxDemo1。
2. 創建一個新網頁,命名為DynamicDisplayControl.aspx。
3. 在頁面中放入一個ScriptManager控件。
4. 放入一個UpdatePanel控件,命名為UpdatePanel1。
5. 在UpdatePanel1控件中放入一個TextBox控件。
6. 在UpdatePanel1控件中放入一個Button控件,命名為Button1,Text屬性設為“...”。
7. 在UpdatePanel1控件中再放入一個UpdatePanel控件,命名為UpdatePanel2。
8. 在UpdatePanel2控件中放入一個SqlDataSource控件,命名為SqlDataSource1,綁定至Northwind數據庫的Customers數據表。
9. 在UpdatePanel2控件中放入一個GridView控件,命名為GridView1,設定DataSoruceID為SqlDataSource1。
10. 勾選GridView1的“Enable Selecting”選項,并設定GridView1的Visible屬性為False。
11. 將UpdatePanel1控件的ChildrenAsTriggers屬性設為False,UpdateMode設為Conditional。
12. 在UpdatePanel1控件的Triggers中加入一個Trigger,ControlID屬性設為GridView1,EventName設為SelectedIndexChanged。
13. 在UpdatePanel2控件的Triggers中加入一個Trigger,ControlID設為Button1,EventName設為Click。
14. 將UpdatePanel2控件的UpdateMode設為Conditional。
15. 在Button1的Click事件中鍵入程序3-1的代碼。
16. 在GridView1的SelectedIndexChanged事件中鍵入程序3-2的代碼。17. 整個UI界面的完成圖應如圖3-1所示。

圖3-1
程序3-1
Samples\3\AjaxDemo1\DynamicDisplayControl.aspx.cs protected void Button1_Click(object sender, EventArgs e) { if (!GridView1.Visible) GridView1.Visible = true; else GridView1.Visible = false; }
程序3-2
Samples\3\AjaxDemo1\DynamicDisplayControl.aspx.cs protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) { TextBox1.Text = (string)GridView1.SelectedDataKey.Value; GridView1.Visible = false; }
完成以上步驟運行程序后,一開始GridView控件并沒有顯示在網頁上,當使用者點擊按鈕后,GridView控件便會顯示在網頁上,在使用者點擊其中一筆數據后,該筆數據的客戶編號就會帶入TextBox控件中,如圖3-2所示。

圖3-2
雖然此例很簡單,其內有兩個重要的觀念卻必須讓讀者們了解。首先,UpdatePanel2控件包在UpdatePanel1控件中,而UpdatePanel1控件的UpdateMode設為Conditional、ChildrenAsTriggers設為Flase,這代表著UpdatePanel1控件不會自動在子控件Postback時刷新,必須明白指定令其更新的Trigger,而在此處所設定更新UpdatePanel1控件的是GridView2的SelectedIndexChanged事件觸發時。這個設計的目的是讓刷新區域縮到最小,當使用者點擊Button控件時,因為該控件是UpdatePanel2控件的Trigger,所以會觸發UpdatePanel2控件刷新而顯示出GridView控件。請注意!頁面上的Button控件并非UpdatePanel1控件的Trigger,所以此次的刷新并沒有刷新UpdatePanel1控件,而只是刷新UpdatePanel2控件而已,在用戶選取一筆數據后,因為GridView控件是UpdatePanel1控件的Trigger,所以會刷新UpdatePanel1控件。結論一,這個例子只在適當的時間刷新適當的UpdatePanel。結論二,GridView控件一開始Visible屬性設為False,也就是說這個控件在初次網頁加載時并不會顯示,也不會做數據綁定的動作,這點大大加快了網頁初次加載的速度。如果換成動態顯示Calendar就更簡單了,請照下面的步驟做。
1. 創建一個新網頁,命名為DynamicDisplayCalendar.aspx。
2. 在頁面中放入一個ScriptManager。
3. 放入一個UpdatePanel控件,命名為UpdatePanel1。
4. 在UpdatePanel1控件中放入一個TextBox控件。
5. 在UpdatePanel1控件中放入一個Button控件,Text屬性設為“...”。
6. 在UpdatePanel1控件中放入一個UpdatePanel控件,命名為UpdatePanel2。
7. 在UpdatePanel2控件中放入一個Calendar控件,命名為Calendar1。
8. 將UpdatePanel1控件的ChildrenAsTriggers屬性設為False,UpdateMode設為Conditional。
9. 在UpdatePanel1控件的Triggers中加入一個Trigger,ControlID設為Calendar,EventName設為SelectionChanged。
10. 在UpdatePanel2控件的Triggers中加入一個Trigger,ControlID設為Button1,EventName設為Click。
11. 將UpdatePanel2控件的UpdateMode設為Conditional。
12. 在Button1控件的Click事件中鍵入程序3-3的代碼。
13. 在Calendar1控件的SelectionChanged事件中鍵入程序3-4的代碼。
運行結果如圖3-3所示。
程序3-3
Samples\3\AjaxDemo1\DynamicDisplayCalendar.aspx.cs protected void Button1_Click(object sender, EventArgs e) { if (Calendar1.Visible) Calendar1.Visible = false; else Calendar1.Visible = true; }
程序3-4
Samples\3\AjaxDemo1\DynamicDisplayCalendar.aspx.cs protected void Calendar1_SelectionChanged(object sender, EventArgs e) { TextBox1.Text = Calendar1.SelectedDate.ToShortDateString(); Calendar1.Visible = false; }

圖3-3
提醒讀者,雖然將Calendar控件放在UpdatePanel控件內可以防止因選取日期而產生的頁面刷新情況,但是這是很沒有效率的做法,因為每次選取日期都會觸發一個Async-Postback動作,而這是沒有必要的。使用不會產生Postback動作、以JavaScript所建構出來的日期控件來取代原有的Calendar控件,才是有效率的做法,ASP.NET AJAX Control Toolkit中就提供了這樣一個控件,第8章將會提到它。