2

这可能看起来像重复,但我不这么认为。我已经搜索过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复制了两个代码。asp:LinkButton

怎么了?我的页面上只有另一个事件RowDataBound

  protected void gvSchoolClasses_RowDataBound(object sender, GridViewRowEventArgs e)
  {
        e.Row.ID = Guid.NewGuid().ToString();
  }

  protected void Page_Load(object sender, EventArgs e)
  {
        CheckAuthentication();

        if (!Page.IsPostBack)
        {
            ClassesAcademicYearLabel.Text = "- Year " + Setting.Year;
            //FillClassesList();  //filling some combo boxes. Have checked the codes here too
            //FillLettersList();  //they didn't affect the Grid
            FillGrid();
        }

        ClassErrorLabel.Visible = false;

  }
4

3 回答 3

3

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

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

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

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

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

ctl00$content$gvSchoolClasses$ctl02$DeleteRow

DeleteRow通过获取声明的 ID(JS 代码可以确信传递此字符串getElementById会以一致、可预测的方式运行。

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

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

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

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

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

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

于 2012-07-10T19:35:16.197 回答
1

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

CommandArgument='<%: Guid.NewGuid.ToString(); %>'

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

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            LinkButton deleteRow = (LinkButton)e.Row.FindControl("DeleteRow");
            if (deleteRow != null)
                deleteRow.CommandArgument = Guid.NewGuid().ToString();
        }
于 2012-07-10T19:56:18.463 回答
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','')
于 2012-07-10T19:39:28.000 回答