[转] ASP.NET AJAX中的嵌套UpdatePanel
ASP.NET AJAX中的嵌套UpdatePanel
我们在实际编程中,经常遇到UpdatePanel嵌套的情况。例如,在一个网上购物系统中,可能需要一个产品种类、子类和产品列表的联动界面。本文探讨一下UpdatePanel的嵌套问题。
1.从一个例子开始
(1) 创建一个“ASP.NET Ajax-Enabled Web Site”站点。
(2) 如果Default.aspx中没有ScriptManager,拖一个进来。
(3) 在Default.aspx中拖入一个UpdatePanel,其ID为UpdatePanel1。
(4) 拖一个Button到UpdatePanel1中,其Text属性设置为“外部刷新”。
(5) 进入源模式,在<ContentTemplate>标签中输入“外部最后刷新:<%=DateTime.Now.ToString() %>”。
(6) 进入设计模式,在UpdatePanel1中再拖入一个UpdatePanel,注意要放到UpdatePanel1内部,ID为UpdatePanel2,这第二个称为嵌套UpdatePanel。
(7) 在UpdatePanel2中拖入一个Button,Text为“内部刷新”。
(8) 进入源模式,在UpdatePanel2的<ContentTemplate>中输入“内部最后刷新:<%=DateTime.Now.ToString() %>”。
(9) 回到设计模式,将两个UpdatePanel的UpdateMode属性都设置成Conditional。
(10) 最后得到的代码如下(我在做例子时把两个Button的ID都改了,本例改不改都可以):
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
内部最后刷新:<%=DateTime.Now.ToString() %>
<br />
<asp:Button ID="btnInner" runat="server" Text="内部刷新" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnOuter" runat="server" Text="外部刷新" />
<br />
外部最后刷新:<%=DateTime.Now.ToString() %>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
(11) 之所以在页面上使用“<%=DateTime.Now.ToString() %>”这样的标记,是因为只要这部分内容刷新了,就会显示当前时间。我们要看的就是这个区域有没有刷新。
(12) 运行程序,可以看到点击“内部刷新”按钮时,只有嵌套的UpdatePanel的时间改变;点击“外部刷新”按钮时,两个时间都会改变,说明两个都刷新了。
2.刷新规则
在一个界面上,可以使用的UpdatePanel的数量没有限制,而且UpdatePanel还可以嵌套(上例)。这里很重要的一个属性是UpdateMode属性。
如果一个UpdatePanel的UpdateMode属性设置为Always,则另外一个UpdatePanel中的某个服务器控件(如按钮)触发了刷新后,这个UpdatePanel也一起刷新。如果UpdatePanel的UpdateMode设置为Conditional,则只有本UpdatePanel中的服务器控件触发刷新,或者嵌套在外部的UpdatePanel中的服务器控件触发刷新后,此UpdatePanel才刷新。
那么产品种类、子类、产品列表三级联动的实例中,我们可以设置三层嵌套,然后将其UpdateMode属性都设置为Conditional。那么我们选择了一个产品种类后,其种类、子类和产品都要刷新;选择了某个子类后,子类和产品会刷新,而种类不刷新。这样就基本达到了要求。
可能有时我们的要求更苛刻一些。考虑到产品种类的刷新是没有意义的,我们希望点击种类时,只有子类和产品刷新,而种类不刷新。
这时就用到了ChildrenAsTriggers属性,该属性表示UpdatePanel内部的控件是否出发回传刷新操作,该属性默认值为true。如果我们把上个例子中外层UpdatePanel的该属性改成false,运行会看到点击“外部刷新”按钮时,没有触发刷新操作(两个时间都没有改变);而点击“内部刷新”按钮时,内部的时间改变了,外边的没有。
这似乎并不符合我们的要求,我们希望的是点击外部按钮后,内部的刷新,而外部的不刷新(就是产品种类不刷新,子类和产品刷新),我们可以用一行程序实现这个功能。
为“外部刷新”按钮增加Click事件,输入以下代码:
protected void btnOuter_Click(object sender, EventArgs e)
{
UpdatePanel2.Update();
}
运行,可以看到不管点击哪个按钮,都只有内部的时间刷新了。
3.母版页中使用UpdatePanel
UpdatePanel不仅可以使用在普通aspx中,还可以用在母版页中。因为母版页和内容页运行时要组合成一个页面,而一个页面中只能有一个ScriptManager,因此ScriptManager只能放到母版页中,而母版页和内容页中都可以放多个UpdatePanel。
同时,如果母版页的ContentPlaceHolder占位控件放到了一个UpdatePanel中,则该UpdatePanel就和内容页的UpdatePanel形成了嵌套关系。