如何在 GridView 中异步回发






4.80/5 (2投票s)
概念:随着 ASP.NET 2.0 AJAX Extensions 1.0 的兴起,开发人员被强大的 AJAX 服务器控件所吸引,但他们忽略了其中一些
概念
随着 ASP.NET 2.0 AJAX Extensions 1.0 的兴起,开发人员被强大的 AJAX 服务器控件所吸引,但他们忽略了其中一些控件如果使用不当可能会造成危害。一个例子是,需要在每一行中都有一个按钮(选择按钮),当单击该按钮时,应触发异步回发以更新页面上由 UpdatePanel 包围的区域。
一种解决方案可能是将整个 GridView 放在 UpdatePanel 中,并且由于 UpdatePanel 具有一个名为“ChildrenAsTriggers”的属性,其默认值为“true”,那么从 GridView 发出的任何回发都将导致异步回发。
但是等等!!
这是否意味着每次单击特定行中的按钮时,整个 GridView 都会回发到服务器,然后在返回时,GridView 会再次刷新? 是的,这是真的,这就是我上面提到的,AJAX 服务器控件应该以正确的方式使用,即 **使用,但不要过度使用**!!
解决方案
情况如下。有一个 UpdatePanel,其中包含一个 Label,用于保存当前的 DateTime 值。在此 UpdatePanel 下方是一个 GridView,其中列出了 AdventureWorks 数据库中 Vendors 数据表中的数据。 对于每一行,都有一个选择按钮,该按钮应触发异步回发,从而更新位于上方 UpdatePanel 中的 Label。 以下是 ASPX 标记
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblName" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1"
AutoGenerateColumns="False" onrowdatabound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="ActiveFlag" HeaderText="ActiveFlag"
SortExpression="ActiveFlag" />
<asp:BoundField DataField="VendorID" HeaderText="VendorID"
InsertVisible="False" ReadOnly="True" SortExpression="VendorID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:TemplateField HeaderText="Command">
<ItemTemplate>
<asp:UpdatePanel ID="gridUpdatePanel" runat="server">
<ContentTemplate>
<asp:LinkButton ID="lbtnSelect" Text="Select" runat="server"
CommandName="Select" onclick="lbtnSelect_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
SelectCommand="SELECT TOP 5 [ActiveFlag], [VendorID], [Name] FROM [Purchasing].[Vendor]" />
一个聪明的想法是将仅包含选择按钮的列放在 UpdatePanel 中,请注意上面代码中的粗体区域。然后,当单击此 LinkButton 时,将进行异步回发并更新主 UpdatePanel 中 Label 的内容。 此外,您需要将第一个 UpdatePanel 上的 UpdateMode 设置为“Conditional”,这样页面上的每个异步回发都不会导致其刷新内容。
剩下要展示的是 LinkButton 的事件处理程序在 C# 中的代码
protected void lbtnSelect_Click(object sender, EventArgs e)
{
this.lblName.Text = DateTime.Now.ToString();
this.UpdatePanel1.Update();
}
正如您所看到的,执行了对 UpdatePanel 的 Update() 方法的调用。 这将导致 UpdatePanel1 在客户端刷新其内容。 正如您之前所看到的,UpdatePanel 没有定义任何触发器,并且将其 UpdateMode 设置为 Conditional,因此刷新其内容的唯一方法是手动调用其 Update() 方法。
在 FireFox 中测试此代码并打开 Firebug 时,我们可以看到服务器返回的响应为
62|updatePanel|UpdatePanel1| <span id="lblName">2/18/2008 6:51:14 PM</span> |165|updatePanel|GridView1_ctl02_gridUpdatePanel| <a id="GridView1_ctl02_lbtnSelect" href="javascript:__doPostBack('GridView1$ctl02$lbtnSelect' ,'')">选择</a> |165|updatePanel|GridView1_ctl03_gridUpdatePanel| <a id="GridView1_ctl03_lbtnSelect" href="javascript:__doPostBack('GridView1$ctl03$lbtnSelect' ,'')">选择</a> |165|updatePanel|GridView1_ctl04_gridUpdatePanel| <a id="GridView1_ctl04_lbtnSelect" href="javascript:__doPostBack('GridView1$ctl04$lbtnSelect','')">选择</a> |165|updatePanel|GridView1_ctl05_gridUpdatePanel| <a id="GridView1_ctl05_lbtnSelect" href="javascript:__doPostBack('GridView1$ctl05$lbtnSelect','')">选择</a> |165|updatePanel|GridView1_ctl06_gridUpdatePanel| <a id="GridView1_ctl06_lbtnSelect" href="javascript:__doPostBack('GridView1$ctl06$lbtnSelect' ,'')">选择</a> |0|hiddenField|__EVENTTARGET||0|hiddenField|__EVENTARGUMENT||704|hiddenField |__VIEWSTATE/ViewState 减少
哦,哪里出错了? 您可以看到整个 GridView 都被刷新了! 这违背了上面提到的目的!! 好吧,不犯错就不会学习! 让我们仔细考虑一下,现在每一行都包含一个 UpdatePanel,每个 UpdatePanel 都有 UpdateMode="Always" 和 ChildrenAsTriggers="True" -- 默认值。 这清楚地解释了为什么单击选择 LinkButton 时整个 GridView 都会刷新。
如何解决这个问题?
您需要做的就是将以下内容添加到 GridView 中的 UpdatePanel 中
UpdateMode="Conditional" ChildrenAsTriggers="false"
这告诉位于 GridView 中的 UpdatePanel,不要在每次异步回发时刷新,并且不要被 UpdatePanel 内容中发生的任何事件刷新。 换句话说,永远不要刷新此 UpdatePanel。 只要您不关心更新 GridView 行中的任何内容,这就成立。 只要您想要执行的操作是刷新 GridView 之外的其他内容,这就是一个很好的解决方案。
现在,再次运行相同的代码并使用 FireFox 和 Firebug 进行测试,您可以看到响应已减少到仅 ViewState 和包含要更新的 Label 的上层 UpdatePanel 的内容
62|updatePanel|UpdatePanel1| <span id="lblName">2/18/2008 7:01:01 PM</span> |0|hiddenField|__EVENTTARGET||0|hiddenField|__EVENTARGUMENT||704|hiddenField|__VIEWSTATE| ViewState 减少您能看到通过添加这两个属性获得了多少吗? 现在您的问题已经通过包含按钮的 GridView 得到解决,该按钮用于更新外部 UpdatePanel 并具有良好的性能提升! 想象一下,对于在 GridView 中显示的大量数据,这将有多么有用?
希望您喜欢这篇文章!
此致