
第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章将会提到它。