Search code examples
c#asp.netgridviewhyperlinkrowdatabound

Can't Find Hyperlink of Cell during Gridview RowDatabound


I have a gridview that lists rows of information from SQL. If the late column is set to 1 it should display the text of the row in red. This works, however the hyperlink text will not be displayed in red. So I'm trying to a) change the forecolor of the hyperlink element or b) apply a class to the element. When I try to retrieve the hyperlink it does not get it. When I retrieve a label it seems to work fine.

ASP

<asp:TemplateField HeaderText="Project">
      <ItemTemplate>
           <a id="hlProject" href="VpnDetails.aspx?Project=<%# Eval("id") %>"><%# Eval("project") %></a>
       </ItemTemplate>
 </asp:TemplateField>
<asp:TemplateField HeaderText="Last Update">
       <ItemTemplate>
           <asp:Label ID="lblLastUpdate" runat="server" Text='<%#Eval("diff") %>'></asp:Label>
       </ItemTemplate>
  </asp:TemplateField>

C#

protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //Adds the tooltip to the last update label
            Label lblLastUpdate = e.Row.FindControl("lblLastUpdate") as Label;
            DateTime activeSince = Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, "begindate"));
            DateTime lastupdate = Convert.ToDateTime(DataBinder.Eval(e.Row.DataItem, "lastupdate"));
            lblLastUpdate.ToolTip = "Active Since " + activeSince.ToString("MMMM d yyyy HH:mm") + " - Last Update " + lastupdate.ToString("MMMM d yyyy HH:mm");

            if (Convert.ToString(DataBinder.Eval(e.Row.DataItem, "late")) == "1")
            {//if the row is late it should be red
                e.Row.Font.Bold = true;
                e.Row.ForeColor = System.Drawing.Color.Red;

                HyperLink hlProject = new HyperLink();
                try
                {
                    hlProject = (HyperLink)e.Row.FindControl("hlProject");
                    hlProject.Attributes.Add("class", "late");
                    hlProject.ForeColor = System.Drawing.Color.Red;
                }
                catch (Exception e1)
                {
                    lblError.Text = e1.Message;
                }
            }
        }

So I need to know why it works for the label and not for the hyperlink. I also need a solution for the hyperlink.


Solution

  • You can't find your hyperlink on the server because it is not a server side control. You need to add runat="server" to do just that. Note the change to the href to make it valid.

    <a id="hlProject" runat="server" href='<%# Eval("id", "VpnDetails.aspx?Project={0}") %>'><%# Eval("project") %></a>
    

    You would then be able to grab it server side by finding it within your row.

    using System.Web.UI.HtmlControls;
    
    protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            HtmlAnchor hlProject = (HtmlAnchor)e.Row.FindControl("hlProject");
        }
    }
    

    Alternatively, you could create and use an ASP.NET Hyperlink control. This is a little more flexible/useful on the server side.

    <asp:HyperLink ID="hlProject" runat="server"
      NavigateUrl='<%# Eval("id", "VpnDetails.aspx?Project={0}") %>'
      Text='<%# Eval("project") %>'>
    </asp:HyperLink>
    
    protected void gvLastIp_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            HyperLink hlProject = (HyperLink)e.Row.FindControl("hlProject");
        }
    }