【问题标题】:Dynamic buttons in GridView - Button.Click event not firingGridView 中的动态按钮 - Button.Click 事件未触发
【发布时间】:2026-01-27 19:45:02
【问题描述】:

我有一个绑定到 AccessDataSource 的 GridView 控件。选择一行后,我在所选行内创建一个表。我正在向此表添加按钮。他们的 Click 事件永远不会被触发。我阅读了有关重新创建按钮和东西的信息,但仍然没有解决问题的运气。感谢您的帮助!

.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AdminSurvey.aspx.cs" Inherits="AdminSurvey" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   <title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="id_survey_grid_view" runat="server" DataSourceID="id_access_data_source"  
              SkinID="default_skin" AllowSorting="True" AutoGenerateColumns="false" 
              OnRowCreated="SurveyGridView_RowCreated">
<Columns>
        <asp:HyperLinkField HeaderText="Title" SortExpression="TITLE"
            DataTextField="TITLE" DataNavigateUrlFields="SURVEY_ID"
            DataNavigateUrlFormatString="~\AdminSurvey.aspx?survey_id={0}">
        </asp:HyperLinkField>
    </Columns>
</asp:GridView>
<asp:AccessDataSource ID="id_access_data_source" runat="server" DataFile="~/App_Data/database.mdb" 
    OldValuesParameterFormatString="original_{0}"
    OnLoad="InitAccessDataSource">
</asp:AccessDataSource>
</form>
</body>
</html>

.cs:

public partial class AdminSurvey : System.Web.UI.Page
{
 private const string ID_BUTTON_SUBMIT = "SUBMIT_BUTTON";
 private const string ID_BUTTON_DELETE = "SUBMIT_DELETE";
 private string _selected_survey;

protected void SurveyGridView_RowCreated(Object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null && !IsPostBack)
    {
        string survey = ((DataRowView)e.Row.DataItem).Row.ItemArray[0].ToString();
        if (survey.Equals(_selected_survey))
        {
            e.Row.Cells[0].Controls.Clear();
            // create table
            e.Row.Cells[0].Controls.Add(createSurveyTable(((DataRowView)e.Row.DataItem).Row.ItemArray[0].ToString(),
                                                    ((DataRowView)e.Row.DataItem).Row.ItemArray[1].ToString(),
                                                    ((DataRowView)e.Row.DataItem).Row.ItemArray[2].ToString()));

            ViewState["row_index"] = Convert.ToString(e.Row.RowIndex);
            ViewState["survey_id"] = ((DataRowView)e.Row.DataItem).Row.ItemArray[0].ToString();
            ViewState["title"] = ((DataRowView)e.Row.DataItem).Row.ItemArray[1].ToString();
            ViewState["description"] = ((DataRowView)e.Row.DataItem).Row.ItemArray[2].ToString();
        }
    } else if(e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null && IsPostBack) {
        string row_idx = (string)ViewState["row_index"];

        if (row_idx != null && e.Row.RowIndex.Equals(Convert.ToInt32(row_idx)))
        {
            _selected_survey = (string)ViewState["survey_id"];
            string title = (string)ViewState["title"];
            string description = (string)ViewState["description"];

            e.Row.Cells[0].Controls.Clear();
            // recreate table
            e.Row.Cells[0].Controls.Add(createSurveyTable(_selected_survey, title, description));
        }
    }
}

private Table createSurveyTable(string survey_id, string title, string description)
{
    Table table = new Table();
    TableRow row = new TableRow();
    TableCell cell = new TableCell();

    Table questions_table = createQuestionsTable(survey_id);

    cell.Controls.Add(questions_table);

    row.Cells.Add(cell);
    table.Rows.Add(row);

    return table;
}

private Table createQuestionsTable(string survey_id)
{

    // submit row
    TableRow submit_row = new TableRow();
    TableCell submit_cell = new TableCell();

    submit_button = new Button();
    submit_button.Text = "Submit";
    submit_button.ID = ID_BUTTON_SUBMIT;
    submit_button.Click += new EventHandler(submitButton_Click);
    submit_cell.Controls.Add(submit_button);

    delete_button = new Button();
    delete_button.Text = "Delete";
    delete_button.ID = ID_BUTTON_DELETE;
    delete_button.Click += new EventHandler(deleteButton_Click);
    submit_cell.Controls.Add(delete_button);

    submit_row.Cells.Add(submit_cell);
    table.Rows.Add(submit_row);

    return table;
}

private void submitButton_Click(object sender, EventArgs e)
{
}

private void deleteButton_Click(object sender, EventArgs e)
}

} // class

【问题讨论】:

  • 您的 createQuestionsTable 方法在 page_load 之后调用,并且您正在为动态按钮添加一个事件,因此您在页面生命周期中非常晚才添加此按钮。您最多必须创建按钮和事件 Page_Load 事件才能正常工作。任何像按钮这样的控件以及在 Page_Load 之后添加的事件都不会适当地触发事件处理程序。

标签: c# asp.net gridview button events


【解决方案1】:

我不想回答我的问题,但我希望它可以节省任何人查看问题的时间。原来,错误出现在 if 条件中:

if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null && !IsPostBack)
{
    // ...
} else if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null && IsPostBack) {
    // ...
}

e.Row.DataItem != null 错误地出现在两个条件中,而第二个条件(IsPostBack 等于 true)从未被执行。

正确的代码是:

if (e.Row.RowType == DataControlRowType.DataRow && e.Row.DataItem != null && !IsPostBack)
{
    // ...
} else if (e.Row.RowType == DataControlRowType.DataRow && IsPostBack)
{
    // ...
}

【讨论】:

    【解决方案2】:

    尝试分配命令名称,并附加到网格的 RowCommand 事件以侦听按钮的点击,作为点击点击事件的替代方法。

    【讨论】:

    • 我为 submit_button 分配了一个 commandName,并向 GridView 添加了一个 RowCommandEventHandler。单击该按钮会导致一个简单的回发。我还尝试在 .aspx 代码中添加一个 asp:buttonfield。按钮域正确触发了事件。然后单击我的旧按钮,解决了使用不正确的命令名引发 RowCommand 事件 - 按钮字段的命令名。
    • 哇,好吧,这很奇怪...尝试在按钮上将 UseSubmitBehavior 设置为 false,这样它将使用 __doPostBack 方法回发...
    • 我做了 submit_button.CommandName = "SUBMIT"; submit_button.UseSubmitBehavior = false;并且“void SurveyGridView_RowCommand(object sender, GridViewCommandEventArgs e)”仍然没有被解雇......