Вопрос

Here is how I'm populating my GridView control. I'm doing this from the code-behind, and not from the .aspx front end. The following is an extremely abbreviated version of what I have:

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();
}

To handle paging the GridView's "AllowPaging" set to true, and I have the following event handler:

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    GridView1.PageIndex = e.NewPageIndex;
    UpdateGridView();
}

And this works great!

However, I also have the RowDataBound event handler:

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 + "'";
    }
}

My goal here is to have the rows themselves be clickable, and lead to another page with a query string that equals that row's ID. I need the value in the ID column so that I can access it when creating the row, so that I can add the ID to the QueryString of the link. But I don't want the ID column to be visible, so I added in the line: e.Row.Cells[0].Visible = false; Doing this breaks the paging functionality. The page numbers no longer show up. If I comment out this one line, it all works, but the ID is visible in the GridView.

1) Why? 2) What can I do to get the same functionality, but with the fewest changes possible?

Это было полезно?

Решение

After much trial and error, I figured it out. This appears to be an extremely rare problem, so there is not much out there on the internet about it, as the conditions are pretty specific. Most of what I read talked about instead of putting the ID in the GridView as just a regular column, to use DataKeyNames instead.

I'm sure that might work, but I needed a solution ASAP, as I had already wasted a significant amount of time wrestling with this.

The solution lies in the GridViews RowDataBound event:

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 + "'";
    }
}

Apparently, if you use e.Row.Cells[0].Visible = false; with no condition as I had in my original question, it somehow interprets that as a sign to make the pager invisible as well. The solution was to include the e.Row.Cells[0].Visible = false; line in the if block, which says only make only the first cell and header of the DataRows (and not other elements like the pager) invisible.

EDIT: I just realized that if you're using GridView sorting, the above will screw up your sorting. To keep sorting enabled, and display the pager, and hide the first column, this did the trick:

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 + "'";
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top