c# - GridView RowCommand 第一次未触发

标签 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','')

我从 asp:LinkBut​​tonhref 复制了单击之前和之后的两个代码。

出了什么问题?我的页面上只有一个其他事件 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;

  }

最佳答案

通过在 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','') 触发回发

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

关于c# - GridView RowCommand 第一次未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11420260/

相关文章:

c# - 更新控件中的 asp.net 面板可见性

android - 如何解析json数据并在 GridView 中显示

xaml - 使用 x :Bind inside the GridView's ItemTemplate layout User Control in UWP

c# - ionic zip : Zip file creation from byte[]

c# - 该名称...在当前上下文中不存在...我们如何切换上下文?

c# - 从 winforms 运行 aspx 页面

c# - Xamarin.Forms 中的框架边框宽度

.net - 什么可以解释托管堆上超过 5,000,000 个 System.WeakReference 实例?

c# - 如何将这 2 种方法重构为 1 种方法?

c# - 将 jQuery 数据表绑定(bind)到 gridview 时出现异常