
第5章ASP.NET AJAX实战篇
5.1 无刷新的数据编辑
有了UpdatePanel控件的强力支持,要结合GridView及DetailsView控件做出无刷新的数据编辑网页就成了小菜一碟。请照着以下步骤做。
1. 新增一个Web Site,命名为AdvAjaxDemo。
2. 新增一个网页,命名为NoRefreshEdit.aspx。
3. 在页面中放入一个ScriptManager控件。
4. 在网页源码中键入程序5-1的程序代码。
5. 切换回设计页面,在Table的第一个Cell中放入一个UpdatePanel控件,命名为UpdatePanel1,UpdateMode设为Conditional。
6. 在UpdatePanel1控件中放入一个SqlDataSoruce控件,命名为SqlDataSource1,配置其联结至Northwind数据库的Customers数据表,选取CustomerID、CompanyName、ContactName、ContactTitle字段。
7. 在UpdatePanel1控件中放入一个GridView控件,命名为GridView1,将DataSourceID设为SqlDataSource1,勾选“Enable Paging”及“Enable Selecting”等选项。
8. 在Table的第二个Cell中放入一个UpdatePanel控件,命名为UpdatePanel2,UpdateMode设为Conditional。
9. 在UpdatePanel2控件中放入一个SqlDataSource控件,命名为SqlDataSource2,配置其联结至Northwind数据库的Customers数据表,选取所有字段,并启用编辑功能。
10. 添加WHERE条件式至SqlDataSource2控件,如图5-1所示。

图5-1
11. 完成SqlDataSource2 控件的配置,点击SelectQuery属性修改参数值来源,如图5-2 所示。

图5-2
12. 放一个DetailsView控件至UpdatePanel2控件中,命名为DetailsView1,将DataSourceID设为SqlDataSource2,将Enable Inserting、Enable Editing、Enable Deleteing等选项打勾。
13. 点击UpdatePanel2控件的Triggers属性,添加一个Trigger,ControlID为GridView1、EventName为SelectedIndexChanged。
14. 在UpdatePanel2控件的Triggers属性再添加一个Trigger,ControlID为GridView1、EventName为PageIndexChanged。
15. 整个完整的.aspx程序代码见程序5-2。
程序5-1
Samples\5\AdvAjaxDemo\NoRefreshEdit.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="NoRefreshEdit.aspx.cs" Inherits="NoRefreshEdit" %> <!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 runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <table> <tr> <td valign=top> </td> <td valign=top> </td> </tr> </table> </div> </form> </body> </html>
运行程序后,一个无刷新的数据编辑页面就呈现在你眼前,如图5-3所示。

图5-3
不过这个网页有个问题,当你编辑了某笔数据后,会立即发现所编辑的数据并未立即反馈到GridView上,如图5-4所示。

图5-4
事实上,数据库中的数据确实已经更新完成,只要切换GridView控件的页次,或者重载网页,便可看到更新后的数据。读者们可能会以为,产生这种现象的症结点在于DetailsView将数据更新后,UpdatePanel1控件并未被刷新,所以只要将DetailsView设定为UpdatePanel1的Trigger即可解决此问题,但事实并非如此简单,即使将DetailsView的ItemDeleted、ItemInserted、ItemUpdated设为UpdatePanel1控件的Trigger也不能解决此问题,那问题出在哪?又该如何解决呢?问题有两个,第一DetailsView控件并非UpdatePanel1的Trigger,所以它的任何动作都不会刷新UpdatePanel1控件。第二即使DetailsView控件成为UpdatePanel1控件的Trigger,它的动作可以导致UpdatePanel1控件刷新,UpdatePanel1控件于刷新时也会因为GridView1控件没有重新绑定SqlDataSource1,而持续显示上一次的列表。明白这两个问题的起源后,便可整理出一个解法:① DetailsView控件的新增、修改、删除动作必须要能同时刷新UpdatePanel1,② DetailsView的新增、修改、删除动作于刷新UpdatePanel1时,必须强制GridView1重新绑定SqlDataSource1,由数据库中取得最新数据。实际操作的方式就是在DetailsView的ItemDeleted、ItemUpdated、ItemInserted事件中,对GridView1下达DataBind指令,接着通过UpdatePanel1的Update函数来要求UpdatePanel1刷新。
程序5-2
Samples\5\AdvAjaxDemo\NoRefreshEdit.aspx.cs protected void DetailsView1_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) { GridView1.DataBind(); UpdatePanel1.Update(); } protected void DetailsView1_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) { GridView1.DataBind(); UpdatePanel1.Update(); } protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e) { GridView1.DataBind(); UpdatePanel1.Update(); }
当UpdatePanel控件的UpdateMode属性为Conditional时,除了可通过Triggers中的设定来要求其何时刷新外,设计师也可以直接于程序代码中调用其Update函数来要求该UpdatePanel刷新。完成后重新运行程序,一切就能正常运作了。