一、UpdatePanel控件属性

ScriptManager和UpdatePanel控件联合使用可以实现页面异步局部更新的效果。其中的UpdatePanel就是设置页面中异步局部更新区域,它必须依赖于ScriptManager存在,因为ScriptManger控件提供了客户端脚本生成与管理UpdatePanel的功能。

1. ScriptManager控件重要的属性:

ScriptManager控件的EnablePartialRendering属性:true-表示实现页面的异步局部更新;false-表示实现全页面的刷新。此属性默认值为true

2. UpdatePanel控件重要的属性:

UpdatePanel控件的RenderMode属性:InLine,UpdatePanel控件被解析成HTML的标记;Block,UpdatePanel控件被解析成HTML控件的

3. UpdatePanel控件的UpdateMode属性:

  • Always,UpdatePanel页面上任何一处发生的回发操作都会产生页局部更新;
  • Conditional,只在特定的情况下才产生页面的回发,如执行UpdatePanel控件的update()方法或在指定的触发器的操作下,UpdatePanel控件的UpdateMode默认为”Always”。

4.UpdatePanel控件的ChildAsTrigger属性:

指示UpdatePanel内部控件引起的回发是否产生当前UpdatePanel控件的局部更新。 如果UpdateMode设为Always的话,那ChildAsTrigger属性必须设为True,否则运行出错。

二、UpdatePanel局部刷新的使用

1. UpdatePanel内部控件引起回发,来更新当前UpdatePanel内部的控件内容

  1. 向页面中加入ScriptManager、UpdatePanel控件和一个Label控件,ID=“Label1”。
  2. 在UpdatePanel中加入一个Button、一个Label,ID=“Label2”。
  3. 双击Button在事件处理程序中写入下列代码:Label2.Text = DateTime.Now.ToString();
  4. 在Page_Load事件中写入下列代码:Label1.Text = DateTime.Now.ToString();
  5. 运行页面,发现每次点击按钮都会产生异步局步刷新,只有Label2的内容发生更改,页面上的Label1时间没有发生更改。
  1. 代码如下:
  2. <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
  3. <asp:ScriptManager ID="ScriptManager1" runat="server">
  4. </asp:ScriptManager>
  5. <asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="True">
  6. <ContentTemplate>
  7. <asp:Label ID="Label2" runat="server"></asp:Label>
  8. <br />
  9. <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
  10. </ContentTemplate>
  11. </asp:UpdatePanel>
  12. 后台代码:
  13. protected void Button1_Click(object sender, EventArgs e)
  14. {
  15. Label2.Text = DateTime.Now.ToString(); ;
  16. }
  17. protected void Page_Load(object sender, EventArgs e)
  18. {
  19. Label1.Text = DateTime.Now.ToString();
  20. }
  21. 注意:此时的ScriptManagerEnablePartialRendering属性应设为true(默认即为true)。UpdatePanelUpdateMode属性应设为Always(默认即为Always)。ChildAsTrigger属性应设为true(默认即为true)。

2. UpdatePanel控件外部的控件引起的回发,来异步更新UpdatePanel内部的内容

虽然上面的方式能够实现很简单地异步局部更新的功能,但就性能方面考虑,我们应当只将数据确实会发生变化的控件摆放在UpdatePanel中,这就可能会出现引起回发的控件不在UpdatePanel内的情况。这个时候我们有两种方式实现这种效果。

A.在Page_Load方法中用ScriptManager1.RegisterAsyncPostBackControl()来注册一下要实现异步更新的控件。

B.用触发器来实现。

1、ScriptManager1.RegisterAsyncPostBackControl()注册的控件可以实现对所有的UpdatePanel控件的异步更新。

  1. 如:ScriptManager1.RegisterAsyncPostBackControl(this.Button2);实现对Button2的注册,那此时Button2的回发就变成一个异步回发(页面不会刷新),它会导致页面上所有的UpdatePanel的内容的更新。
  2. 注意:此时的ScriptManagerEnablePartialRendering属性应设为trueUpdatePanelUpdateMode属性应设为Always

2、ScriptManager1.RegisterAsyncPostBackControl()注册的控件可以实现针对特定UpdatePanel控件的异步更新。

  1. a. 把页面上所有的UpdatePanel控件的UpdateMode设为Conditional
  2. b. ScriptManager1.RegisterAsyncPostBackControl(this.Button2);实现对Button2的注册。
  3. c. Button2控件的Click事件中后面加入后面的代码:UpdatePanel1.Update();
  4. 这样Button2按钮只对UpdatePanel1控件实现的异步的局部刷新。
  5. 注意:这里的UpdatePanel的属性要设为Conditional,如果这里多个UpdatePanel控件都设置为Always的话,所有的UpdatePanel都不会出现刷新的效果。
  6. 如果将其中Button2事件代码UpdatePanel1.Update()对应的UpdatePanel设置为Conditional时,则多个UpdatePanel都会出现刷新的效果,要实现多个UpdatePanel
  7. 其中一个实现更新效果的话,需要将UpdatePanelUpdateMode都设置为Conditional才可以

3、触发器

  1. 如果页面上有多个UpdatePanel控件,如果要实现外部的控件的回发引发指定的UpdatePanel更新的话,那应当要为实现刷新的UpdatePanel控件建立一个触发器。
  2. a. 选中要进行局部更新的UpdatePanel控件。
  3. b. 在其属性页中点击Triggers集合属性右边的小按钮。
  4. c. 在弹出的对话框中的成员列表中添加一个AsyncPostBackTriggers成员。
  5. d. 指定AsyncPostBackTriggers成员的ControlIDEventName,即引发异步回送的控件的ID和该控件的事件。
  6. 完成以上步骤后,切换到HTML页面就会出现下列代码:
  1. <asp:UpdatePanel ID="UpdatePanel2" runat="server" RenderMode="Inline" UpdateMode="Conditional">
  2. <ContentTemplate>
  3. <asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
  4. </ContentTemplate>
  5. <Triggers>
  6. <asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
  7. </Triggers>
  8. </asp:UpdatePanel>
  9. <asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="ButtonOut" />
  1. e. bd的步骤可以直接在html页面中UpdatePanel控件内<ContentTemplate></ContentTemplate>之后添加<Triggers><asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" /></Triggers>,和上面步骤产生的代码是一样的
  2. 这里需要大家注意的是:
  3. 把所有的UpdatePanel控件的UpdateMode设为"Conditional",这样才能够针对建有相关触发器的UpdatePanel更新。
  4. 一个UpdatePanel上可以建有多个触发器,实现在不同的情况下对该UpdatePanel控件内容的更新。示例如下:
  1. <Triggers>
  2. <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click"/>
  3. <asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click"/>
  4. <asp:PostBackTrigger ControlID="Button3" EventName="Click"/>
  5. </Triggers>

3. 两个UpdatePanel控件,其中一个UpdatePanel内的控件引发两个UpdatePanel控件的同时刷新。

a. 在页面上放入两个UpdatePanel和一个ScriptManager控件。
b. 在UpdatePanel1中加入一个标签Label1、一个按钮Button1 ,在UpdatePanel2中加入一个标签Label2。
c. 将UpdatePanel1和UpdatePanel2两个控件的的UpdateMode属性设为”Always”
d. 在Button1的Click事件中加入下面的代码:
  1. protected void Button1_Click(object sender, EventArgs e)
  2. {
  3. Label1.Text = DateTime.Now.ToString();
  4. Label2.Text = DateTime.Now.ToString();
  5. }

e. 或者只在Page_Load事件中填写如下代码即可

  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3. Label1.Text = DateTime.Now.ToString();
  4. Label2.Text = DateTime.Now.ToString();
  5. }

4. 两个UpdatePanel控件,其中一个UpdatePanel内的控件引发当前的UpdatePanel控件的刷新,而另一个不刷新。

a. 步骤和上面的(三)一样
b. 要把UpdatePanel1和UpdatePanel2两个控件的UpdateMode属性设为Conditional,这里需要注意,如果将一个设置为Conditional,一个设置为Always则两个都会刷新的
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” UpdateMode=“Conditional”>
  4. <asp:Label ID=“Label1” runat=“server” Text=“Label”></asp:Label>
  5. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click1 Text=“更新两个UpdatePanel” />
  6. </asp:UpdatePanel>
  7. <asp:UpdatePanel ID=“UpdatePanel2” runat=“server” UpdateMode=“Conditional”>
  8. <asp:Label ID=“Label2” runat=“server” Text=“Label”></asp:Label>
  9. </asp:UpdatePanel>

5. 两个UpdatePanel控件,其中一个UpdatePanel内的控件引发另一个UpdatePanel控件的刷新,而本身不刷新。

a. 步骤和上面的(四)一样(两个都设置为Conditional)之后,还需要
b. 把UpdatePanel1和UpdatePanel2的ChildrenAsTriggers属性设为false
c. 在UpdatePanel2控件中加入一个触发器,触发源设到UpdatePanel1控件内的Button1的Click事件上。
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” UpdateMode=“Conditional” ChildrenAsTriggers=“False”>
  4. <asp:Label ID=“Label1” runat=“server” Text=“Label”></asp:Label>
  5. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click1 Text=“只更新UpdatePane2” />
  6. </asp:UpdatePanel>
  7. <asp:UpdatePanel ID=“UpdatePanel2” runat=“server” UpdateMode=“Conditional”>
  8. <asp:Label ID=“Label2” runat=“server” Text=“Label”></asp:Label>
  9. <asp:AsyncPostBackTrigger ControlID=“Button1” EventName=“Click” />
  10. </asp:UpdatePanel>

三、UpdatePanel控件复杂应用

如:UpdatePanel控件的嵌套、在母版页中使用UpdatePanel、在用户控件中使用UpdatePanel以及在GridView中使用UpdatePanel等。
其实这些操作也免不了对UpdatePanel控件的UpdateMode属性、ChildrenAsTrigger属性以及触发器的使用,下面是系统地说明。

1. 两个嵌套的UpdatePanel控件,外部的UpdatePanel内的控件回发引发二者同时更新

在页面上放一个ScriptManager和UpdatePanel控件(UpdatePanel1),在UpdatePanel1中放入一个标签控件 (lb1)、一个按钮(Button1)和另一个UpdatePanel控件(UpdatePanel2),在UpdatePanel2控件中放一 个标签控件lb2。
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” UpdateMode=“Conditional”>
  4. <asp:Label ID=“lb1” runat=“server”></asp:Label>
  5. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click2 Text=“Button” />
  6. <asp:UpdatePanel ID=“UpdatePanel2” runat=“server” UpdateMode=“Conditional”>
  7. <asp:Label ID=“lb2” runat=“server”></asp:Label>
  8. </asp:UpdatePanel>
  9. </asp:UpdatePanel>
在Button1控件中的Click事件中加入下面的代码:
  1. protected void Button1_Click2(object sender, EventArgs e)
  2. {
  3. lblIn.Text = DateTime.Now.ToString();
  4. lblOut.Text = DateTime.Now.ToString();
  5. }
要实现外部UpdatePanel内控件的回发引起内部和外部两个UpdatePanel控件的同时刷新的话,需要把两个UpdatePanel控件的 UpdateMode都设为Conditional,这样外部UpdatePanel内的控件回发会自动引起内部UpdatePanel控件的刷新。
注意:外部UpdatePanel控件的ChildrenAsTrigger属性要设为True,两个UpdatePanel控件的UpdateMode要都设为 Conditional,如果UpdateMode设为Always的话也会出现两个UpdatePanel同时刷新的效果,这样会导致页面上其它的 UpdatePanel控件也发生刷新。

2. 两个嵌套的UpdatePanel控件,内部的UpdatePanel内的控件回发引发二者同时更新

在页面上放一个ScriptManager和UpdatePanel控件(UpdatePanel1),在UpdatePanel1中放入一个标签控件 (lb1)和另一个UpdatePanel控件(UpdatePanel2),在UpdatePanel2控件中放一个标签控件lb2和一个按 钮(Button1)。
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” UpdateMode=“Conditional”>
  4. <asp:Label ID=“lb1” runat=“server” ></asp:Label>
  5. <asp:UpdatePanel ID=“UpdatePanel2” runat=“server” UpdateMode=“Conditional”>
  6. <asp:Label ID=“lb2” runat=“server” ></asp:Label>
  7. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click Text=“Button” />
  8. </asp:UpdatePanel>
  9. <asp:AsyncPostBackTrigger ControlID=“Button1” EventName=“Click” />
  10. </asp:UpdatePanel>
在按钮的Click事件中和(一)中的一样。
注意:把两个UpdatePanel控件的UpdateMode属性设为Conditional,要把内部控件ChildrenAsTrigger设为 True。但这样内部UpdatePanel内的控件只引发自身的刷新,不会引发外部的UpdatePanel控件的刷新,不会刷新外部的 UpdatePanel控件,因此我们还需要为外部UpdatePanel控件加入一个触发器,触发源指定为Button1控件的Click事件上。

3. 两个嵌套的UpdatePanel控件,外部的UpdatePanel内的控件回发只引发内部控件的更新

在页面上放一个ScriptManager和UpdatePanel控件(UpdatePanel1),在UpdatePanel1中放入一个标签控件 (lb1)、一个按钮(Button1)和另一个UpdatePanel控件(UpdatePanel2),在UpdatePanel2控件中放一个标签控件lb2。
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” UpdateMode=“Conditional” ChildrenAsTriggers=“False”>
  4. <asp:Label ID=“lb1” runat=“server” ></asp:Label>
  5. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click Text=“Button” />
  6. <asp:UpdatePanel ID=“UpdatePanel2” runat=“server” UpdateMode=“Conditional”>
  7. <asp:Label ID=“lb2” runat=“server” ></asp:Label>
  8. <asp:AsyncPostBackTrigger ControlID=“Button1” EventName=“Click” />
  9. </asp:UpdatePanel>
  10. </asp:UpdatePanel>
在按钮的Click事件中和(一)中的一样。
注意:要把两个UpdatePanel控件的UpdateMode设为Conditional,把外部UpdatePanel控件的 ChildrenAsTrigger设为false。这样两个UpdatePanel控件都不会刷新,所以还要为内部的UpdatePanel控件建立触 发器,触发源指向外部UpdatePanel中的的Button1的Click事件上。

4. 母版页中使用UpdatePanel控件

如果将ScriptManager控件添加在母版页上的话,那么各内容页面就没必要再添加ScriptManager控件了,只需添加UpdatePanel控件就可以了,因为母版页和内容页面将来生成的是一个页面的实例,而在一个页面上是不允许同时存在两个ScriptManager控件的。
如果ScriptManager控件没有添加在母版页上的话,那只能把ScriptManager控件添加在其中一个内容页面里。不要向每一个内容页面中添加ScriptManager控件。
1. 内容页面中的UpdatePanel内的控件引起回发,只更新当前内容页面的内容。
此时按钮分别在各自的UpdatePanel控件内。
将两个内容页面内的两个UpdatePanel控件的UpdateMode设为Conditional,ChildrenAsTrigger设为True。
在按钮的Click事件中和(一)中的一样。
这样就出现各内容页的UpdatePanel内的按钮只对当前内容页起作用。
2. 在母版页中的按钮引起回发,更新指定内容页的信息。
此时有两个按钮:ButtonOut在母版页中,ButtonIn在内容页面1中。
当点击ButtonOut时,异步更新两个内容页面的信息。当点击ButtonIn时,异步更新母版面中的UpdatePanel1中的信息。
母版页HTML代码如下:
  1. <asp:ScriptManager ID=“ScriptManager1” runat=“server”>
  2. </asp:ScriptManager>
  3. <asp:UpdatePanel ID=“UpdatePanel1” runat=“server” RenderMode=“Inline” UpdateMode=“Conditional”>
  4. <asp:Label ID=“lbl” runat=“server” Text=“Label”></asp:Label>
  5. </asp:UpdatePanel>
  6. <asp:Button ID=“Button1” runat=“server” OnClick=“Button1_Click Text=“ButtonOut” />
  1. <table width=80%>
  2. <tr>
  3. <td>
  4. <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  5. </asp:contentplaceholder>
  6. </td>
  7. <td bgcolor=maroon>
  8. <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
  9. </asp:ContentPlaceHolder>
  10. </td>
  11. </tr>
  12. </table>
  13. <br />

内容页面的HTML代码如下:

  1. <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Child.aspx.cs" Inherits="Child" Title="UpdatePanel Test Page" %>
  2. <%@ MasterType VirtualPath="~/MasterPage.master" %>
  3. <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
  4. <asp:UpdatePanel ID="UpdatePanel1" runat="server">
  5. <ContentTemplate>
  6. <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
  7. <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="ButtonInner" />
  8. </ContentTemplate>
  9. </asp:UpdatePanel>
  10. </asp:Content>
  11. <asp:Content ID="Content2" runat="server" ContentPlaceHolderID="ContentPlaceHolder2">
  12. <asp:UpdatePanel ID="UpdatePanel2" runat="server">
  13. <ContentTemplate>
  14. <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
  15. </ContentTemplate>
  16. </asp:UpdatePanel>
  17. </asp:Content>

母版页的CS代码如下:

  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3. ScriptManager1.RegisterAsyncPostBackControl(this.Button1);
  4. }
  5. protected void Button1_Click(object sender, EventArgs e)
  6. {
  7. Label lbl1 = (Label)this.ContentPlaceHolder1.FindControl("Label1");
  8. lbl1.Text = DateTime.Now.ToString();
  9. Label lbl2 = (Label)this.ContentPlaceHolder2.FindControl("Label2");
  10. lbl2.Text = DateTime.Now.ToString();
  11. }
  12. public string BindTitle
  13. {
  14. get
  15. {
  16. return lbl.Text;
  17. }
  18. set
  19. {
  20. lbl.Text = value;
  21. }
  22. }

Child孩子页面的CS代码如下:

  1. protected void Button1_Click(object sender, EventArgs e)
  2. {
  3. Label1.Text = Master.BindTitle;
  4. Master.BindTitle = "ContentPage1's Action";
  5. ((UpdatePanel)Master.FindControl("UpdatePanel1")).Update(); ;
  6. }

5. 用户控件中使用UpdatePanel控件

如果父页面中存在ScriptManager控件,那用户控件的页面中不应再放入ScriptManager控件了,只在用户控件中加入UpdatePanel。
其控件的回发与更新规律与使用方式与母版页一样。 在asp.net中ScriptManager用UpdatePanel弹出提示对话框时,常常会出现错误,可以试着用这种方法解决,
  1. protected void FinishButton_Click(object sender, EventArgs e)
  2. {
  3. ScriptManager.RegisterStartupScript(this.UpdatePanel1,
  4. this.GetType(), "FinishButton", "<script>alert ('OK');</script>", false);
  5. }
FinishButton为要求弹出对话框的按钮。