由 UpdatePanel 内 GridView 内的 LinkBut​​ton 触发的完整回发

Posted

技术标签:

【中文标题】由 UpdatePanel 内 GridView 内的 LinkBut​​ton 触发的完整回发【英文标题】:Full postback triggered by LinkButton inside GridView inside UpdatePanel 【发布时间】:2011-06-19 19:44:39 【问题描述】:

我在 UpdatePanel 中有一个 GridView。在模板字段中是我用于标记项目的按钮。从功能上讲,这可以正常工作,但该按钮始终会触发整页回发而不是部分回发。如何获取触发部分回发的按钮?

<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
    <ContentTemplate>
        <asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
            AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="">
                    <ItemTemplate>
                        <asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
                            CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Name" HeaderText="Name" />
                <asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
                <asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
                <asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>

【问题讨论】:

我在一个新项目上创建了这个场景。我无法让您的完整回发发生,每次都是部分回发。在您的情况下,您还能想到其他奇怪的因素吗? 你能在“MarkAsComplete”命令上发布你正在做什么的代码吗? 确保您没有在 Firefox 上使用网络开发工具禁用所有 javascript 【参考方案1】:

您需要将每个 LinkBut​​ton 注册为 AsyncPostBackTrigger。在GridView中绑定每一行后,您需要搜索LinkBut​​ton并通过代码隐藏注册它,如下所示:

protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)  
  
   LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;  
   ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);  
  

这还需要为 LinkBut​​ton 设置 ClientIDMode="AutoID",如 here 所述(感谢 Răzvan Panda 指出这一点)。

【讨论】:

@Lionel 在下面提到了一些我发现除了这个答案之外非常有用的东西。在OrderGrid_RowDataBound 处理程序内部,检查当前行是否为数据行是明智的(因为您要查找的“LinkBut​​ton”可能不在标题行上)。 if (e.Row.RowType == DataControlRowType.DataRow) LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton; ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb); 否则,当您找不到该按钮的 ID 时,您将获得 NPE。 如果您的 Gridview 不在 UpdatePanel 中,这将不起作用。请改用 RowCreated【参考方案2】:

这可能是旧的,但我的解决方案是在 itemTemplate 内放置一个更新面板,在 gridview 之外放置一个。

触发器应该是gridview,外部触发器应该是gridview和PageIndexChanging。试试看。

【讨论】:

除了您的答案之外,您还应该确保包含您为解决方案找到的代码,以帮助未来的读者解决同样的问题。【参考方案3】:

我遇到了一个问题,我的一个表单工作正常 (page1),另一个做整个回帖 (page2)。结果当我制作第二页时,我做了太多cut/paste,它仍然在表单定义中有一个javascript 调用。

< form id="form1" runat="server" onsubmit="return checkstuff();">

但是checkstuff 没有在page 2 中定义。

删除了onsubmit,部分帖子开始工作。

在工作页面 - 第 1 页中,定义了 checkstuff,但它只是一个存根,它只返回 true。只是为了笑,我在checkstuff 中发出警报,果然,所有提交都调用它,无论是否部分提交。而且,如果我将存根更改为只返回 false,则什么也没有发生。

在这一切中,javascript 仍在运行,就好像正在提交一个完整的页面。因此,请仔细检查您的客户端脚本。

【讨论】:

【参考方案4】:

我的网格视图处于条件模式。

protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
    
        if (e.Row.RowType == DataControlRowType.DataRow) 
            LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
            AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
            trigger.ControlID = lnk.UniqueID;
            trigger.EventName = "Click";
            UpdatePanel2.Triggers.Add(trigger);

        
    

在我放的链接按钮的点击事件中:

protected void LinkButton2_Click(object sender, EventArgs e)
    
        UpdatePanel2.Update();
    

【讨论】:

你的gridview处于条件模式是什么意思? 这会产生错误An exception of type 'System.InvalidOperationException' A control with ID 'LinkButton2' could not be found for the trigger in UpdatePanel 'UpdatePanel2'【参考方案5】:

您需要为每个 RowState 注册每个控件。 1:为 RowState = Alternate 和 Normal 注册您的控件) 2:为 RowState = Edit 注册您的控件 3:...

ASPX:

<asp:TemplateField HeaderText="">
                <ItemTemplate>
                    <asp:LinkButton runat="server" ID="Btn1" 
                        CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
                </EditItemTemplate>
            </asp:TemplateField>

后面的代码:

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)

    if (e.Row.RowType == DataControlRowType.DataRow 
        && (e.Row.RowState == DataControlRowState.Normal 
            || e.Row.RowState == DataControlRowState.Alternate))
    
        LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton; 
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
    
    if (e.Row.RowType == DataControlRowType.DataRow 
        && e.Row.RowState == DataControlRowState.Edit)
    
        LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );      
    

【讨论】:

欢迎来到 Stack Overflow!额外的解释会改善你的答案。【参考方案6】:

可能不建议这样做,但您可以通过排除 AsyncPostBackTrigger 上的 EventName 来使 GridView 上的所有内容异步工作,例如

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>

这将使 RowCommand 事件和 GridView 上的任何其他事件异步触发。另请注意,当您在 GridView 上设置 ClientIDMode="Static" 时,它将导致完整的回发。

【讨论】:

谢谢! ClientIDMode="Static" 是问题所在!删除它时它会再次起作用。 “当您在 GridView 上创建 ClientIDMode"Static" 时,将导致完整回发”的注释非常有用。此信息与强制将每个 LinkBut​​ton 注册为异步回发控件一起为我修复了它,因为由于其他原因我无法摆脱 ClientIDMode="Static"。非常感谢!【参考方案7】:

将以下元素放入 web.config 文件中的 system.web 元素中

<xhtmlConformance mode="Transitional"/>

【讨论】:

【参考方案8】:

MSDN 指定 UpdatePanel.ChildrenAsTriggers 属性“[g] 设置或设置一个值,该值指示来自 UpdatePanel 控件的直接子控件的回发是否更新面板的内容”(请参阅​​http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx)。

由于您的 LinkBut​​ton 似乎不是“直接子控件”,因此我建议将您的 LinkBut​​ton 配置为显式 AsyncPostBackTrigger。

在您的 标签下,尝试添加:

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>

【讨论】:

这不起作用,因为该控件 ID 在行外不可见。

以上是关于由 UpdatePanel 内 GridView 内的 LinkBut​​ton 触发的完整回发的主要内容,如果未能解决你的问题,请参考以下文章

GridView中使用 jQuery DatePicker (UpdatePanel)

如何从 Gridview 中的 LinkBut​​ton 触发 Onclick 事件驻留在 updatePanel 中?

Gridview Jquery DatePicker中的Asp.Net UpdatePanel

在 javascript 中查找控件

通过 Postback 在 UpdatePanel 中保留 DIV 的滚动位置

使用 JavaScript 或 jQuery 手动更新 UpdatePanel