由 UpdatePanel 内 GridView 内的 LinkButton 触发的完整回发
Posted
技术标签:
【中文标题】由 UpdatePanel 内 GridView 内的 LinkButton 触发的完整回发【英文标题】: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】:您需要将每个 LinkButton 注册为 AsyncPostBackTrigger
。在GridView中绑定每一行后,您需要搜索LinkButton并通过代码隐藏注册它,如下所示:
protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)
LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;
ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);
这还需要为 LinkButton 设置 ClientIDMode="AutoID"
,如 here 所述(感谢 Răzvan Panda 指出这一点)。
【讨论】:
@Lionel 在下面提到了一些我发现除了这个答案之外非常有用的东西。在OrderGrid_RowDataBound
处理程序内部,检查当前行是否为数据行是明智的(因为您要查找的“LinkButton”可能不在标题行上)。 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"
时,将导致完整回发”的注释非常有用。此信息与强制将每个 LinkButton 注册为异步回发控件一起为我修复了它,因为由于其他原因我无法摆脱 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)。
由于您的 LinkButton 似乎不是“直接子控件”,因此我建议将您的 LinkButton 配置为显式 AsyncPostBackTrigger。
在您的 标签下,尝试添加:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>
【讨论】:
这不起作用,因为该控件 ID 在行外不可见。以上是关于由 UpdatePanel 内 GridView 内的 LinkButton 触发的完整回发的主要内容,如果未能解决你的问题,请参考以下文章
GridView中使用 jQuery DatePicker (UpdatePanel)
如何从 Gridview 中的 LinkButton 触发 Onclick 事件驻留在 updatePanel 中?
Gridview Jquery DatePicker中的Asp.Net UpdatePanel