【问题标题】:Dynamically adding a command button to a GridView将命令按钮动态添加到 GridView
【发布时间】:2011-01-19 15:58:20
【问题描述】:

我在尝试向网格中添加按钮时遇到问题。我的 GridView 首先在 PageLoad 事件中加载数据。

然后,我将获取每行第一个单元格中的数据,并创建一个链接到 URL 的按钮。要获取 URL,我必须使用第一个单元格中的数据作为参数运行查询。起初我是在 RowDataBound 事件中执行此操作的,但是为每一行都点击该查询会使其非常慢。

所以我决定添加一个按钮,该按钮仅在您单击该按钮时才检索 URL。

这是我的 GridView:

<asp:GridView ID="gvResults" runat="server"
    OnRowDataBound="gvResults_RowDataBound"
    OnRowCommand="gvResults_RowCommand">               
</asp:GridView>    

还有我的代码:

protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.DataItem != null)
    {
        LinkButton lb = new LinkButton();
        lb.CommandArgument = e.Row.Cells[0].Text;
        lb.CommandName = "NumClick";
        lb.Text = e.Row.Cells[0].Text;

        e.Row.Cells[0].Controls.Add((Control)lb);
    }
}


protected void gvResults_RowCommand(object sender, CommandEventArgs e)
{
    switch (e.CommandName.ToLower())
    {
        case "numclick":
            string url = GetUrl(e.CommandArgument.ToString());
            Response.Redirect(url);
            break;
        default:
            break;
    }
}

网格生成良好,按钮被添加到每一行的网格中。但是当我点击它时,不会触发 RowCommand 事件,并且页面只是刷新。

有谁知道问题出在哪里?

【问题讨论】:

  • 在将其添加到 Cell 之前,我会将 ID 关联到 linkBut​​ton。

标签: c# asp.net


【解决方案1】:

为什么要使用动态按钮?您可以轻松地将链接按钮直接放入 gridview 的标记中(只要您不介意使用模板字段),并且无需搞乱 RowDataBound 事件。

您的标记将如下所示:

<Columns>
    <asp:TemplateField HeaderText="SomeHeaderText">
            <ItemTemplate>
                <asp:LinkButton ID="lnkBtn" runat="server" CommandName="NumClick" CommandArgument= '<%# (string)Eval("dbValue") %>'  Text='<%# (string)Eval("dbValue") %>'></asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>        
    <asp:BoundField></asp:BoundField>
    <asp:BoundField></asp:BoundField>
    <asp:BoundField></asp:BoundField>
</Columns>

向 RowCommand 事件添加断点,并确保您可以命中断点。

问题可能出在其他地方。

另外,请确保您没有在回发时进行数据绑定。

【讨论】:

  • 这就是问题所在,我确实在 RowCommand 事件中添加了一个断点,但该事件从未触发。而且我不是回发数据绑定。
  • 太棒了。尽可能多地尝试和使用标记总是一个好习惯。如果可以将某些内容从您的代码中移出以进行标记,那么就去做吧。
  • 如果我有动态填充的网格视图..那么我不能在标记中声明字段,因为列数可能每次都会改变。那我们应该怎么做..
【解决方案2】:

您的代码有很大问题。我很难解释你的大错误是什么,但我可以很容易地告诉你如何解决。

问题是您在RowDataBound 事件中生成了一个新按钮,这绝对是最错误的选择。该按钮被渲染是因为它在页面渲染时在该事件之后存在,但在数据绑定之前不存在。如果每次加载页面时都绑定数据(即使在回发期间),按钮仍然会被渲染,因为您生成了一个新按钮。

但是由于按钮在数据绑定之前不存在,所以它不能引发事件。您必须将按钮从标记声明到 GridView 模板中,然后不要使用新的LinkButton() 而是使用e.Row.Cells[0].FindControl("buttonId") 访问它并设置其文本。然后,您必须设置它的标记以触发 它自己的 Command 事件(不是 RowCommand)并按照您使用的方式处理它(不要忘记在数据绑定期间设置 CommandArgument )

[Edit] 我也犯了一个错误:数据绑定控件中的控件在数据绑定之前也不存在。但是它们不是用new Control()(通过数据绑定控制的私有方法)初始化的,而是用Page.LoadControl(typeof(Control))初始化的。这是动态加载控件时必须解决的第一件事!

【讨论】:

  • 我也有几乎相同的问题。我有一个动态网格,我在其中附加了两个事件。Rowcommand 和 rowdatabound。在行数据绑定事件中,我添加了一些编辑和删除按钮。我可以在其他地方的每一行添加那些编辑和删除按钮吗
【解决方案3】:

因为控件是在数据绑定上动态添加的,并且您必须为每个回发数据绑定网格视图,所以每次“单击”的控件都是不同的。该事件不会触发,因为在它需要触发的时候它并不像在页面的最后一次迭代中那样存在。

我注意到您没有任何逻辑来确定按钮是否应该在那里,并且它总是进入单元格 [0]。

您应该将此按钮放入 TemplateItem 中,以便它正确存在。如果您需要在代码隐藏中执行此操作,最好在 RowCreated 事件中执行此操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多