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

时间:2010-02-02 17:28:05

标签: asp.net events postback linkbutton

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

  1. 传统的事件处理程序(“OnClick”)
  2. GridView级别的OnRowCommand事件处理程序。
  3. 在这两种情况下,我都进行了调试,甚至没有捕获事件处理程序。

    如果我在页面上移动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"
    

    它会回发,但在举起活动时从不暗示

    知道我在这里缺少什么吗?

3 个答案:

答案 0 :(得分:10)

你如何约束你的GridView?您使用的是数据源控件吗?如果在Page_Load期间手动绑定,则可能由于网格每次往返都绑定,因此事件处理程序无法正常捕获。如果是这种情况,您可能需要尝试类似:

protected void Page_Load(object sender, EventArgs e)
{
    if(!Page.IsPostBack)
    {
        //do binding
    }
}

您可以发布样本绑定代码以与标记一起使用吗?

如果你真的想要强制解决问题,你可以挂钩Grid上的RowDataBound事件,手动找到按钮并在后面的代码中添加处理程序。类似的东西:

标记摘录:

<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事件一样。

您是否有使用模板字段的原因? Vs说ButtonField?如果您使用ButtonField,则可以挂钩RowCommand事件。

标记摘录:

<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文档:

修改

在ButtonField上回答你的问题 - 是的,我不明白为什么你还不能处理按钮字段。这是一个片段,用于在行数据绑定期间找到按钮字段并将其隐藏(未经测试但我认为可行...)

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;
        }
    }
}

答案 1 :(得分:0)

您的GridView上是否已启用viewstate?这让我多次失望。

答案 2 :(得分:-1)

<button onclick="window.open('<%#Eval("ReportLinks")%>', '_blank');" title='<%#Eval("ReportLinks")%>'> Link</button>