为啥 GridView 中的 LinkButton 不会引发其 OnClick 事件?
Posted
技术标签:
【中文标题】为啥 GridView 中的 LinkButton 不会引发其 OnClick 事件?【英文标题】:Why won't my LinkButton inside a GridView raise its OnClick event?为什么 GridView 中的 LinkButton 不会引发其 OnClick 事件? 【发布时间】:2011-01-12 06:33:02 【问题描述】:我在 GridView 中有一个 LinkButton(通过 TemplateField)。无论我尝试什么,LinkButton 都不会调用它的事件处理程序。我都试过了:
-
传统的事件处理程序(“OnClick”)
GridView 级别的 OnRowCommand 事件处理程序。
在这两种情况下,我都进行了调试,它甚至没有捕获事件处理程序。
如果我将 LinkButton 移出页面(所以它不在 GridView 中),它可以正常工作,所以我知道语法是正确的。
这里是“传统”方法:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" OnClick="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
有趣的是,如果我从后面的代码中删除“CancelThis”方法,它会引发错误。所以我知道它知道它的事件处理程序,因为它会在编译时查找它。
这里是 RowCommand 方法:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton Text="Cancel" ID="DeleteButton" CausesValidation="false" CommandName="CancelThis" runat="server" />
</ItemTemplate>
<asp:TemplateField>
在这种情况下,GridView 有:
OnRowCommand="GridView_RowCommand"
它回发,但从不提示引发事件。
知道我在这里缺少什么吗?
【问题讨论】:
【参考方案1】:你是如何绑定你的GridView
的?您是否使用数据源控件?如果您在Page_Load
期间手动绑定,则可能由于网格每次往返都绑定,事件处理程序没有正确捕获。如果是这种情况,您可能想尝试以下方法:
protected void Page_Load(object sender, EventArgs e)
if(!Page.IsPostBack)
//do binding
您能否发布示例绑定代码以配合您的标记?
如果您真的想要强制执行该问题,您可以挂钩到 Grid 上的 RowDataBound 事件,手动找到按钮并在后面的代码中添加处理程序。比如:
标记sn-p:
<asp:GridView ID="gvTest" runat="server" OnRowDataBound="gvTest_RowDataBound" />
后面的代码:
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
if(e.Row.RowType == DataControlRowType.DataRow)
//find button in this row
LinkButton button = e.Row.FindControl("DeleteButton") as button;
if(button != null)
button.Click += new EventHandler("DeleteButton_Click");
protected void DeleteButton_Click(object sender, EventArgs e)
LinkButton button = (LinkButton)sender;
// do as needed based on button.
我不确定按钮的用途是什么,但假设它是一个行删除按钮,您可能不想像在事件处理程序中那样采用这种方法,您无法直接访问问题,就像您使用 RowCommand
事件一样。
您使用“模板”字段是否有原因?与说ButtonField
?如果您使用ButtonField
,则可以挂钩RowCommand
事件。
标记sn-p:
<asp:GridView ID="gvTest" runat="server" OnRowCommand="gvTest_RowCommand">
<columns>
<asp:buttonfield buttontype="Link" commandname="Delete" text="Delete"/>
....
</columns>
</asp:GridView>
后面的代码:
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)
if(e.CommandName == "Delete")
//take action as needed on this row, for example
int rowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow currentRow = (sender as GridView).Rows[rowIndex];
//do something against the row...
您可能需要参考 MSDN 文档,了解其中一些主题:
RowCommandEvent ButtonField class编辑:
回答您关于 ButtonField 的问题 - 是的,我不明白为什么您仍然不能处理按钮字段。这是一个 sn-p,用于在绑定行数据期间找到按钮字段并将其隐藏(未经测试,但我认为可行......)
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
if (e.Row.RowType == DataControlRowType.DataRow)
//let's assume your buttonfield is in column 1
// (you'd know this based on your markup...)
DataControlFieldCell cell = e.Row.Cells[1] as DataControlFieldCell;
if(cell != null)
ButtonField field = cell.ContainingField as ButtonField;
//based on your criteria, show or hide the button
field.Visible = false;
//or
field.Visible = true;
【讨论】:
使用 ButtonField,有没有办法以编程方式隐藏或显示它?我可能会或很多人不会显示按钮,这取决于当前迭代中的某些值。我读到的所有内容都说我必须切换到 TemplateField 中的标准按钮。使用我当前的方法,我使用 RowDataBound 事件来检查当前迭代,找到按钮并可能隐藏它。 我认为这绝对是可能的。用附加的示例代码编辑了我的答案。【参考方案2】:是否在您的 GridView 上打开了视图状态?这让我无数次感到困惑。
【讨论】:
【参考方案3】:<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>
【讨论】:
以上是关于为啥 GridView 中的 LinkButton 不会引发其 OnClick 事件?的主要内容,如果未能解决你的问题,请参考以下文章
由 UpdatePanel 内 GridView 内的 LinkButton 触发的完整回发
使用确认警报 ASP.Net 单击 Gridview LinkButton 上的突出显示行
在 Gridview 中使用 TemplateField 和 jQuery Datatable