65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 GridView 中异步回发

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (2投票s)

2013 年 10 月 11 日

CPOL

4分钟阅读

viewsIcon

50961

概念:随着 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 中显示的大量数据,这将有多么有用?

 

希望您喜欢这篇文章!
此致

© . All rights reserved.