[学习目标]
F 理解并掌握ScriptManager控件的使用
F 了解ScriptManager控件的使用
F 理解并掌握Timer控件的使用
F 理解并掌握UpdatePanel控件的使用
F 理解并掌握UpdateProgress控件的使用
【本章简介】
Ajax Extensions是Asp.NetAJAX框架的核心组件,只有使用它提供的服务,才能实现局部刷新和个性化组件的AJAX效果。
AJAXExtensions是整个Asp.NetAJAX框架的灵魂,它提供全局脚本的管理控制,提供异步获取数据功能,提供页面中某一部分的局部更新,还可以使用定时器实现任务的自动执行。
AJAXExtensions核心组件主要包括以下几个控件:ScriptManager、UpdatePanel、UpdateProgress、Timer和ScriptManagerProxy,下面我们对其中主要的控件逐一进行讲解。
Ajax Extensions |
描述 |
ScriptManager |
管理支持 AJAX 的 ASP.NET 网页的客户端脚本。默认情况下,ScriptManager 控件会向页面注册 Microsoft AJAX Library 的脚本。这将使客户端脚本能够使用类型系统扩展并支持部分页呈现和 Web 服务调用这样的功能。注意一个页面只能有一个该控件。 |
ScriptManagerProxy |
当已在父元素中定义 ScriptManager 控件时,使嵌套组件(如内容页和用户控件)可以将脚本和服务引用添加到页中。比如ScriptManager位于master页面,该控件位于内容页面(子页面)。 |
Timer |
按定义的时间间隔执行回发。如果将 Timer 控件用于 UpdatePanel 控件,则可以按定义的时间间隔启用部分页更新。也可以使用 Timer 控件来发送整个页面。 |
UpdatePanel |
可生成功能丰富的、以客户端为中心的 Web 应用程序。通过使用 UpdatePanel 控件,可以刷新页的选定部分,而不是使用回发刷新整个页面。这称为执行“部分页更新”。包含一个 ScriptManager 控件和一个或多个 UpdatePanel 控件的 ASP.NET 网页可自动参与部分页更新,而不需要自定义客户端脚本。 |
UpdateProgress |
来显示部分页更新的进度。如果页包含 UpdatePanel 控件,则也可以包含 UpdateProgress 控件,以便通知用户部分页更新的状态。可以使用一个 UpdateProgress 控件来表示整个页的部分页更新的进度。或者,可以为每个 UpdatePanel 控件包含一个 UpdateProgress 控件。 |
本章的下面几节将介绍这些服务器端控件,以及如何在Asp.Net程序中使用它们。
在Asp.Net AJAX领域中,最重要的控件是ScriptManager服务器端控件,它处理页面,允许进行部分页面的呈现。每个要使用Asp.Net AJAX功能的页面都需要使用一个ScriptManager控件。它又叫做全局脚本控制器,在每个页面上只能有一个,相当于在这个页面上注册框架。
ScriptManager控件负责管理在页面上使用的JavaScript库,并在服务器和客户机之间来回编组信息,完成部分页面的呈现过程。
如果仅在Asp.Net页面上放置了ScriptManager控件,它就会负责加载Asp.Net AJAX需要的JavaScript库。
注意: |
页上使用 ScriptManager 控件注册的任何脚本以及所有事件处理脚本必须位于页上的 form 元素内。否则,将不会注册或执行脚本。 |
ScriptManager控件的语法格式:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
一个网页只能包含一个 ScriptManager 控件,该控件既可以直接位于页面中,也可以间接位于嵌套组件或父组件内部。使用 ScriptManagerProxy 控件,可在母版页或宿主页已包含 ScriptManager 控件的情况下,将脚本和服务添加到内容页和用户控件中。
在使用 ScriptManagerProxy 控件时,可以将脚本和服务添加到 ScriptManager 控件所定义的脚本和服务集合。如果不希望在包含特定 ScriptManager 控件的每一页上都包含特定的脚本和服务,则可以将这些脚本和服务从 ScriptManager 控件中移除。可以通过改用 ScriptManagerProxy 控件,将这些脚本和服务添加到各页中。
在VisualStudio2005项目中模板页上添加ScriptManager之后,最简单的页面代码如下程序清单3-1所示:
程序清单3-1
<%@Master Language="C#" AutoEventWireup="true"CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>无标题页</title>
</head>
<body>
<formid="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1"runat="server">
</asp:ScriptManager>
<asp:contentplaceholder id="ContentPlaceHolder1"runat="server">
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
在VisualStudio 2008母版也上,有直接添加AJAX Master Page的选项。
如果正在使用Asp.Net2.0的母版页,而且同时还在使用Asp.Net AJAX框架,你可能会考虑把ScriptManager控件放在模板页而不是每个内容页中。然而,当需要在某个内容页上引用JavaScript文件或Web服务时就会遇到麻烦了。由于每个页面上只能有一个ScriptManager控件,因此不得不在每一个使用Asp.Net AJAX的页面上引用JavaScipt文件或服务,哪怕某些页面根本就不需要那些外部资源。
为了解决这个问题,Asp.NetAJAX 提供了ScriptManagerProxy控件。这个控件与ScriptManager的功能一样,当页面上已经有一个ScriptManager控件的时候,就可以使用它了。
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Scripts>
<asp:ScriptReferencePath="MyScript.js"/>
</Scipts>
</asp:ScriptManagerProxy>
当某个宿主页面上已经有一个ScriptManager控件,而又需要向其添加一个拥有AJAX功能的Asp.Net用户控件时,ScriptManagerProxy控件也同样可以派上用场。
UpdatePanel控件又叫做更新面板,它用来实现页面的无刷新效果。在使用时,只需要把更新的内容放在该控件的内容面板中即可。
UpdatePanel控件是一个容器控件,这表示它没有相关的UI项。它是引发部分页面会送的方式,仅更新UpdatePanel指定的部分页面。
UpdatePanel的语法格式:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always">
</asp:UpdatePanel>
n UpdatePanel 控件又一个重要的属性UpdateMode,它表示该更新面板采用何种方式来获取服务器端的资源。它有两种模式:Always和Conditional。
ü Always模式表示,在每次客户端浏览器向服务器端请求的时候,都无条件刷新该更新面板中的内容。
ü Conditional模式表示,有触发条件的更新。该触发条件可能是某一个控件的事件,或者其他可以引起更新的条件等。
n UpdatePanel有两个重要的子元素,分别是<ContentTemplate>和<Trigger>。
ü <ContentTemplate>元素是更新面板的内容面板,这和GridView等控件的模板类似,可以在其中添加任何控件。
ü <Triggers>元素是可以更新面板的触发器,只有在触发条件满足后才更新<ContentTemplate>元素中的内容。
1. 建立一个包含ScriptManager和UpdatePanel的页面,在UpdatePanel上添加一个标签和按钮控件,在外部页面也加一个标签控件,程序代码如程序清单:
程序清单3-2 利用UpdatePanel实现局部更新时间
<%@ Page Language="C#"AutoEventWireup="true" CodeFile="Default.aspx.cs"Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<formid="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server" />
<div>
<asp:UpdatePanel ID="UpdatePanel1"runat="server">
<ContentTemplate>
<asp:LabelID="Label1" runat="server"Text="Label"></asp:Label>
<asp:ButtonID="Button1" runat="server"OnClick="Button1_Click" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Label ID="Label2" runat="server" Text="外部时间"></asp:Label></div>
</form>
</body>
</html>
2. C# 代码为:
protected voidPage_Load(object sender, EventArgs e)
{
Label2.Text = DateTime.Now.ToString();
}
protected void Button1_Click(object sender,EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
1. 在创建好的3-2项目中添加一个ScriptManager、UpdatePanel、GridView和一个按钮控件到页面。
2. 数据表内容为某银行客户的数据表,如图3-1所示:
图3-1:某银行客户交易信息表
3. 该文件的HTML关键代码如程序清单3-3所示:
程序清单3-3利用UpdatePanel实现局部更新数据表内容1
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server"/>
<div>
<asp:UpdatePanel ID="UpdatePanel1"runat="server">
<ContentTemplate>
<asp:GridView ID="gvUserData"runat="server"Width="800px">
</asp:GridView>
<asp:Button ID="btnRefresh"runat="server"Text="刷 新" Width="135px"OnClick="btnRefresh_Click"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
4. 然后,我们把GridView绑定到表userdata表,需要用户自己建立数据库Bank,查询交易记录在前三条的账户信息。
后台的关键代码如程序清单3-4所示:
程序清单3-4:利用UpdatePanel实现局部更新数据表内容2
protected void Page_Load(objectsender, EventArgs e)
{
if (!Page.IsPostBack)
{
ShowUserData();
}
}
protected voidbtnRefresh_Click(object sender, EventArgs e)
{
ShowUserData();
}
/*从数据库读数据的方法.*/
public voidShowUserData()
{
string selSql = "selecttop 3 * from userdata order by 记账日期desc";
gvUserData.DataSource = DBHelper.GetDataSet(selSql).Tables[0];
gvUserData.DataBind();
}
5.效果验证,运行程序,将显示数据库表userdata中的最近前三条数据,将数据库中的支出金额由“49.4”修改为“49.45”,点击“刷新”按钮,发现数据在页面无刷新的情况下改变,如图3-2所示。即浏览器的客户端按钮仍然为灰色不可用,因为尽管我们的数据更新了,但是并没有刷新浏览器,所以不涉及页面返回问题。
图3-2:修改数据库表并点击“刷新”按钮实现无刷新效果
该程序用到了Web.Config和DBHelper.Cs,详见项目3-2。
从项目一和项目二我们知道,只要把需要数据更新的控件和触发数据更新的控件都放在UpdatePanel中就可以快速地实现AJAX效果了。但是,假如我们想利用UpdatePanel外的控件来控制数据更新,来实现AJAX效果呢?在此问题基础上,Asp.Net为UpdatePanel控件提供了一个重要属性Triggers,使用Triggers属性可以实现触发器效果。
下面来做个小案例,步骤如下:
1. 新建WEB项目3-3,在页面中添加ScriptManager、UpdatePanel、Label和Button。该文件的HTML关键代码如程序清单3-5所示:
程序清单3-5:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server"/>
<div>
<asp:UpdatePanel ID="UpdatePanel1"runat="server">
<ContentTemplate>
<asp:Label ID="lblMsg" runat="server"Text="Label"></asp:Label><br />
<asp:Button ID="btnDateTime"runat="server"Text="显示日期和时间" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
后台代码为:
protected void btnDateTime_Click(objectsender, EventArgs e)
{
lblMsg.Text= DateTime.Now.ToString();
}
运行程序,单击按钮会实现无刷新更新,但是如果我们把按钮放在UpdatePanel,效果如何呢?你会发现,单击“显示日期和时间”按钮后,页面被整个刷新,并没有达到无刷新的效果。如图3-3所示:
3.为了实现无刷新效果,只要使用UpdatePanel控件的Triggers属性即可。在HTML代码标签</ContentTemplate>后面添加如下代码:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnDateTime" Event="Click"/>
</Triggers>
其中ControlID为用来生成该事件的控件ID,EventName用于刷新事件的名称。UpdatePanel另外一个触发器是PostBackTrigger用来实现整个页面的回送,一般不用。现在运行程序,单击按钮,发现控件即使在UpdatePanel外部也实现了无刷新效果。如图3-4所示:
Timer控件用于间隔一定的时间自动刷新页面或完成特定的任务。它是定时控件,在实际开发中,我们经常使用Timer控件来完成自动刷新功能,比如聊天室聊天内容的即时更新、“世界杯”比赛中的夺冠国家统计、电气考核指标的实时数据等,都可以通过使用Timber控件的定时功能来实现。使用Timer控件还可以打造属于Web的时钟以显示系统时间。
Timer控件仍然主要通过Interval属性和Tick事件来实现其功能,与Winform中的类似。
例如,现在要做一个实时更新的奥运金牌榜排行,就可以通过Timer控件来实现。
本案例可以参考项目三,需要在Web页面添加ScriptManager、UpdatePanel、Timer和GridView控件。
在UpdatePanel控件的</ContentTemplate>标签后,假如代码为:
<Triggers>
<asp:AsyncPostBackTriggerControlID= "Timer1" EventTime="Tick"/>
</Triggers>
在Timer_Click事件中写从数据库中获得安金牌、银牌、铜牌从高到低的前10个国家的排名sql语句即可。
其中Interval表示执行Tick任务的间隔时间,单位是毫秒,这样我们一秒钟更新一次数据,你可以根据需要设置Interval具体的值。
在现实的网络中,当我们打开某一个网站或链接时,由于种种原因经常要等待页面显示出来,这样的用户体验真的很差。如果能在页面执行较长时间操作的同时,给用户提供一个类似于浏览器状态栏那样的进度条,将会很大地改善用户体验。所以微软在ASP.NETAjax中为我们提供了UpdateProgress控件,它可以轻松的实现这样的功能。
在下面示例中,我们模拟一个缓慢的服务器处理过程,这将使Asp.Net AJAX在服务器端代码执行的过程中显示一个等待信息框。代码如程序清单3-6所示:
程序清单3-6:使用UpdateProgress的等待信息框
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpdateProgress.aspx.cs" Inherits="_Default"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"runat="server"/>
<div>
<asp:UpdatePanel ID="UpdatePanel1"runat="server">
<ContentTemplate>
<asp:Button ID="Button1"runat="server"OnClick="Button1_Click"Text="测试UpdateProgess控件" /><br />
<asp:Label ID="Label1" runat="server"Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1"runat="server"AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<div style="font-weight:bold;border:solid 2px black;left: 200px; width: 194px; color: blue; position:relative;
top: 150px; height:20px; background-color: #ffff99;">
正在加载数据,请稍候...
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>
using System.Data;
using System.Configuration;
using System.Web;
usingSystem.Web.Security;
using System.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected voidPage_Load(object sender, EventArgs e)
{
}
protected voidButton1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
Label1.Text= DateTime.Now.ToLongDateString();
}
}
注意:如果异步回发只需要很少的时间,UpdateProgress控件显示的时间也就会很短,这样造成一个让人很不舒服的闪烁效果。这时,可能就需要使用UpdateProgress控件的DisplayAfter属性。该属性指定在显示UpdateProgress控件的<ContentTemplate>中的内容之前所需要等待的毫秒数,设置一定的延迟可以避免闪烁效果。
@ 本章总结
1. 本章介绍了Asp.Net AJAX的服务器控件。
2. ScriptManager控件在每一个Asp.Net AJAX页面上都要有,并且只能有一个。
3. 常常把需要更新的内容放在UpdatePanel控件的内容模板中,以实现无刷新效果。
4. UpdatePanel控件的Triggers属性,一般在其UpdateMode属性设置为Conditional时用到。
5. UpdateProgress控件用来在更新过程中给出提示。
6. Timer控件可以用来做时钟显示系统时间,也可以定时完成特定的任务,它主要使用Interval属性和Tick属性来实现。
& 课后练习
1. 以下不属于Asp.Net AJAX核心组件的是()
A. ScriptManager
B. Timer
C. UpdatePanel
D. Calendar
2. 以下关于ScriptManager控件的描述正确的是( )(选两项)
A. 它是更新面板,需要把更新的部分放在该控件的模版中。
B. 它在每个Asp.Net AJAX页面中都必须有。
C. 它是客户端控件,不需要设置“runat=server”。
D. 它在每个Asp.Net AJAX页面中只能有一个。
3. 以下关于UpdatePanel控件的描述不正确的是( )
A. 它是更新面板,实现无刷新时,常把需要更新的部分放在该控件的模板中。
B. 它的UpdateMode属性,可以设置为Always或Conditional。
C. 当UpdateMode属性设置为Always时,Triggers属性不生效。
D. 当UpdateMode属性设置为Conditional时,Triggers属性不生效。