Seems to be easy but I am having a hard time with this.
<asp:TemplateField HeaderText="ID" InsertVisible="False" SortExpression="id">
<ItemTemplate>
<a href="/visit.aspx?Id=<%#Eval("Id")%>" id="ID" name="ID"> <%#Eval("Id")%> </a>
</ItemTemplate>
</asp:TemplateField>
There is a button in the last column of gridview. Click this button updated the database and refreshed gridview. It also look at the id column in gridview and tries to highlight the row that was edited.
The code works without any problem if ID field is bounded field and is not a URL. But when it is a URL, I cannot seem to read the text value of the URL. I have tried various solution (help from SO and online)
HyperLink link = (HyperLink)row.FindControl("id"); // did not work
((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]).Text // did not work
This is the code snippet that I need help with
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
if (row.RowType == DataControlRowType.DataRow)
{
HyperLink link = (HyperLink)row.FindControl("id");
if (((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]).Text == button.CommandName)
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
}
I am using button.CommandName to store the ID field which works fine. I just can't seem to find the hyperlink control in the gridview inside a template field.
I am getting the following error which does not make sense to me
Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl'
to type 'System.Web.UI.WebControls.HyperLink'.
Update1
This code works without hitch, if I do not use hyperlink field.
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
if (row.Cells[0].Text.Equals(button.CommandName))
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
If change the column 0 to hyperlink and change the code corresponding, then it does not work. Clearly reading the wrong cell is not the problem.
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
HtmlAnchor anchor = (HtmlAnchor) row.Cells[0].Controls[0];
if ( anchor.InnerText.Equals(button.CommandName))
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
Best Answer
First things first - you are trying to
FindControl("id");
where your control in the design view is actuallyID
- Case matters.Another thing - this also appears to be because
<a>
isn't actually aHyperLink
control, but actually aHtmlGenericControl
- thus trying to cast your control is resulting in nothing.You could do one of two things - change your code-behind to get
HtmlGenericControl link = (HtmlGenericControl )row.FindControl("ID");
Or change your design view and use an
<asp:Hyperlink>
control instead of the HTML<a>
Your error
Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' (which is a
in HTML terms) to type 'System.Web.UI.WebControls.HyperLink'.
Is saying
((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]
that the control at position 0 in the first cell on the row your processing is a literal and NOT a link. You can try to fudge it by looking at Controls[1] instead.you can view the rendered HTML of your table and verify this - your link will be nested in a span, or next to a span..
Examine the
Controls
in debug and see what is actually contained in it.Update
There is a lot of confusion over HOW your calling your code. You have
e.Row.RowType
which leads me to believe you're doing this inRowDataBound
.If this is the case then you do NOT need to loop through all of your gridview rows as this method gets called on every row - so you would be calling each row, then each row in the grid.. MASSIVE amount of looping going on for a big grid.
So try this instead - it is only interested on that one row.
also - not sure where you;re getting your
button.CommandName
fromFor this you will need to examine your FindControl method to make sure it actually IS a hyperlink control
last update...
Ok - after more comments I reckon you need to recursively search for the control. this is because
FindControl
will only look at the direct controls within a control. it will not find controls within controls within your control - I.E FindControl looks at the first children only and not grandchildren.So create this method where ever you like:
Then pass in your row and the ID of the control you're looking for.
So like this - change:
to this - notice i kept your lowercase
id
- not sure if you are using lowercase or uppercase - this method will hunt out the little bugger for you :)Once you have your control you can cast it to what you need/or it should be