GridView RowCommand第一次没有触发

时间:2012-07-10 19:11:59

标签: c# asp.net gridview

这可能看似重复但我不这么认为。我已经搜索过stackoverflow,可能还不够。

这是我的挑战:

<asp:LinkButton runat="server" ID="DeleteRow" CommandName="deleterow" 
   CommandArgument='<%# Eval("ID") %>' Text="Delete" 
   OnClientClick="return confirm('Are you sure you want to delete this record?');" /> 

如果您第一次单击该链接,则不会触发OnRowCommand。当你第二次点击它时,它可以工作。

我查看了源代码,我有这些差异。

//When you first load the page: the GUID is the PK for that row 
1. javascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')

//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')

我复制href的{​​{1}}中的两个代码,用于点击之前和之后。

有什么问题?我的网页asp:LinkButton上只有一个其他活动。

RowDataBound

3 个答案:

答案 0 :(得分:3)

通过在RowDataBound事件中设置行的ID属性,您已经创建了正在观察的问题。

由于在页面的控件已添加到集合之后才会触发RowDataBound事件,因此ASP.NET无法更新已计算的客户端引用。因此,命令不会以您期望的方式被触发。

我注意到您已经将CommandArgument属性设置为RowDataBound事件中生成的ID,这也可能是您问题的一部分(取决于触发事件的顺序;我没有方便的管道图。)

编辑:快速解决这个问题的方法是简单地设置ClientID属性(对不起,不是确切的名称,但智能感知应该让你完成其余部分)到某种手动,而不是自动确定。这样,您设置的ID永远不会被框架更改。

为了详细说明您遇到此问题的原因,请考虑提供客户端ID:

ctl00$content$gvSchoolClasses$ctl02$DeleteRow

通过获取声明的ID(DeleteRow)并连续向上走控制层次结构并将父ID添加到字符串,可以保证此ID唯一(对于此页面)。 JS代码可以确信将此字符串传递给getElementById将以一致,可预测的方式运行。

为了能够生成所述ID,层次结构中的所有控件必须已经存在并由渲染引擎计算。

现在让我们考虑当控件的ID属性发生更改时会发生什么(请注意,这不是ClientID,而只是名称为ID的属性。)

ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow

您将注意到,它现在具有您生成并分配给它的GUID,而不是行的命名容器(cl02)。尝试使用以前分配的ID访问此容器的客户端JS将会失望,因为它将无法按预期工作!

当ASP.NET控件通过调用javascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')

触发回发时

回发后会发生正常和花花公子,但是(并且你可以通过检查回发的形式参数来验证这一点)当服务器处理请求时,它将尝试重新水化(来自viewstate)一个没有的控件不存在。因此,它将创建一个新的控件实例(具有正确的ID),该实例不知道已发出命令,因此XXXCommand事件永远不会被触发。由于没有发生数据绑定(它是回发,并且您的代码正确检查了该条件),因此永远不会重置ID,并且可以正常触发命令

答案 1 :(得分:1)

不要更改RowDataBound事件中的Row.ID。要么在网格中更改不同的值,要么在gridview标记中执行此操作:

CommandArgument ='&lt;%:Guid.NewGuid.ToString(); %GT;'

如果您想在代码中执行此操作,则可以执行以下操作:

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            LinkButton deleteRow = (LinkButton)e.Row.FindControl("DeleteRow");
            if (deleteRow != null)
                deleteRow.CommandArgument = Guid.NewGuid().ToString();
        }

答案 2 :(得分:0)

您需要将行索引设置为链接按钮的CommandArgument而不是guid

正如你所说它第二次有效,但html如下所示

//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')