这是我填充 GridView 控件的方式。 我是从代码隐藏中执行此操作,而不是从 .aspx 前端执行此操作。 以下是我所拥有的内容的极其缩写的版本:
private void UpdateGridView()
{
DataTable temptable = new DataTable();
DataColumn idcol = new DataColumn();
DataColumn titlecol = new DataColumn();
idcol.ColumnName = "ID";
titlecol.ColumnName = "Title";
temptable.Columns.Add(idcol);
temptable.Columns.Add(titlecol);
...(get data from the database, store it as variable "x")...
DataRow tempdr;
tempdr[idcol] = x.ID;
tempdr[titlecol] = x.Title;
temptable.Rows.Add(tempdr);
GridView1.DataSource = temptable;
GridView1.DataBind();
}
为了处理分页,将 GridView 的“AllowPaging”设置为 true,我有以下事件处理程序:
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
UpdateGridView();
}
这效果很好!
但是,我也有 RowDataBound 事件处理程序:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false; //hide the ID
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = "location.href='newsindex.aspx?NewsArticleID=" + e.Row.Cells[0].Text + "'";
}
}
我的目标是让行本身可单击,并引导到另一个页面,该页面的查询字符串等于该行的 ID。 我需要 ID 列中的值,以便在创建行时可以访问它,这样我就可以将 ID 添加到链接的 QueryString 中。 但我不希望 ID 列可见,因此我在行中添加了:
e.Row.Cells[0].Visible = false;
这样做会破坏分页功能。 页码不再显示。 如果我注释掉这一行,一切正常,但 ID 在 GridView 中可见。
1)为什么? 2) 我该怎么做才能获得相同的功能,但需要进行尽可能少的更改?
经过多次尝试和错误,我明白了。 这似乎是一个极其罕见的问题,因此互联网上没有太多关于它的信息,因为条件非常具体。 我读到的大部分内容都谈到,不要将 ID 作为常规列放在 GridView 中,而是使用 DataKeyNames。
我确信这可能有用,但我需要尽快找到解决方案,因为我已经浪费了大量时间来解决这个问题。
解决方案在于GridViews RowDataBound事件:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].Visible = false; //hide the ID
e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = "location.href='newsindex.aspx?NewsArticleID=" + e.Row.Cells[0].Text + "'";
}
}
显然,如果您像我在最初的问题中那样无条件地使用
e.Row.Cells[0].Visible = false;
,它会以某种方式将其解释为使寻呼机不可见的标志。 解决方案是在 if 块中包含 e.Row.Cells[0].Visible = false;
行,该行表示仅使 DataRows 的第一个单元格和标题(而不是寻呼机等其他元素)不可见。
编辑:我刚刚意识到,如果您使用 GridView 排序,上面的内容会搞砸您的排序。 要保持排序启用,并显示分页器,并隐藏第一列,这就成功了:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[0].Visible = false; //hide the ID
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = "location.href='newsindex.aspx?NewsArticleID=" + e.Row.Cells[0].Text + "'";
}
}
}