c# gridview row click

When I click on a row in my GridView, I want to go to a other page with the ID I get from the database.

In my RowCreated event I have the following line:

e.Row.Attributes.Add(
     "onClick",
     ClientScript.GetPostBackClientHyperlink(
          this.grdSearchResults, "Select$" + e.Row.RowIndex));

To prevent error messages i have this code:

protected override void Render(HtmlTextWriter writer)
{
    // .NET will refuse to accept "unknown" postbacks for security reasons. 
    // Because of this we have to register all possible callbacks
    // This must be done in Render, hence the override
    for (int i = 0; i < grdSearchResults.Rows.Count; i++)
    {
        Page.ClientScript.RegisterForEventValidation(
                new System.Web.UI.PostBackOptions(
                    grdSearchResults, "Select$" + i.ToString()));
    }
    // Do the standard rendering stuff
    base.Render(writer);
}

How can I give a row a unique ID (from the DB) and when I click the row, another page is opened (like clicking on a href) and that page can read the ID.


Solution 1:

Martijn,

Here's another example with some nifty row highlighting and a href style cursor:

protected void gvSearch_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    e.Row.Attributes.Add("onmouseover", "this.style.backgroundColor='#ceedfc'");
    e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=''");
    e.Row.Attributes.Add("style", "cursor:pointer;");
    e.Row.Attributes.Add("onclick", "location='patron_detail.aspx?id=" + e.Row.Cells[0].Text + "'");
  }
}

The code above works in .NET 3.5. However, you can't set your id column to Visible="false" because you'll get a blank query string value for your id key:

<asp:GridView ID="gvSearch" runat="server" OnRowDataBound="gvSearch_RowDataBound" AutoGenerateColumns="false">
  <Columns>
    <asp:BoundField DataField="id" Visible="false" />
    <asp:BoundField DataField="first_name" HeaderText="First" />
    <asp:BoundField DataField="last_name" HeaderText="Last" />
    <asp:BoundField DataField="email" HeaderText="Email" />
    <asp:BoundField DataField="state_name" HeaderText="State" />
  </Columns>
</asp:GridView>

So change the first column to this instead:

<asp:BoundField DataField="id" ItemStyle-CssClass="hide" />

Add this css to the top of your page:

<head>
  <style type="text/css">
    .hide{
      display:none;
    }
  </style>
<head>

But to hide the first cell of your header row, add this to your gvSearch_RowDataBound() in code-behind:

if (e.Row.RowType == DataControlRowType.Header)
{
  e.Row.Cells[0].CssClass = "hide";
}

Obviously, you could have hidden the id column in code-behind too, but this will result in more text in your markup than a css class:

e.Row.Cells[0].Attributes.Add("style", "display:none;");
e.Row.Attributes.Add("style", "cursor:pointer;");

Solution 2:

I have the solution.

This is what i have done:

if(e.Row.RowType == DataControlRowType.DataRow)
{
    e.Row.Attributes["onClick"] = "location.href='view.aspx?id=" + DataBinder.Eval(e.Row.DataItem, "id") + "'";
}

I have putted the preceding code in the RowDataBound event.

Solution 3:

protected void gvSearch_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        string abc = ((GridView)sender).DataKeys[e.Row.RowIndex].Value.ToString();
        e.Row.Attributes["onClick"] = "location.href='Default.aspx?id=" + abc + "'";    
    }
}