为啥 GridView 中的 LinkBut​​ton 不会引发其 OnClick 事件?

Posted

技术标签:

【中文标题】为啥 GridView 中的 LinkBut​​ton 不会引发其 OnClick 事件?【英文标题】:Why won't my LinkButton inside a GridView raise its OnClick event?为什么 GridView 中的 LinkBut​​ton 不会引发其 OnClick 事件? 【发布时间】:2011-01-12 06:33:02 【问题描述】:

我在 GridView 中有一个 LinkBut​​ton(通过 TemplateField)。无论我尝试什么,LinkBut​​ton 都不会调用它的事件处理程序。我都试过了:

    传统的事件处理程序(“OnClick”) GridView 级别的 OnRowCommand 事件处理程序。

在这两种情况下,我都进行了调试,它甚至没有捕获事件处理程序。

如果我将 LinkBut​​ton 移出页面(所以它不在 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 中的 LinkBut​​ton 不会引发其 OnClick 事件?的主要内容,如果未能解决你的问题,请参考以下文章

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

使用确认警报 ASP.Net 单击 Gridview LinkBut​​ton 上的突出显示行

更新asp.net GridView中的行时出错

在 Gridview 中使用 TemplateField 和 jQuery Datatable

UpdatePanel 中 ListView 中的 LinkBut​​ton 导致完全回发

android中gridview的item为啥不能居中