I have the following GridView
, which has as DataSource
a List<T>
:
<asp:GridView ID="gvDownloads" UseAccessibleHeader="False"
AutoGenerateColumns="False" runat="server" PageSize="10" AllowPaging="true"
CellPadding="4" CellSpacing="1" GridLines="None" DataKeyNames="productid">
<EmptyDataTemplate>
No licenses found
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="Id" >
<ItemTemplate>
<%# Eval("ProductId")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product Name">
<ItemTemplate>
<%# Eval("ProductName")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Stock Code">
<ItemTemplate>
<%# Eval("StockCode")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Which renders correctly and with the proper values.
Now, I would like to modify on the fly the field StockCode and in order to do so I have in my code behind:
Sub gvDownloads_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvDownlads.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
e.Row.Cells(2).Text = StockCodeConverter.Convert(e.Row.Cells(2).Text)
End If
End Sub
But the data cells corresponding to StockCode are empty. Now I tried to debug and for some reason the code finds just the value of the header row. The values of the other rows are string.Empty
or &nsbp. Might it depend on the List as DataSource?
Use ASP.NET controls instead, for example Labels
:
If e.Row.RowType = DataControlRowType.DataRow Then
Dim lblStockCode = DirectCast(e.Row.FindControl("lblStockCode"), Label)
lblStockCode.Text = StockCodeConverter.Convert(lblStockCode.Text)
End If
on aspx:
<asp:TemplateField HeaderText="Stock Code">
<ItemTemplate>
<asp:Label Id="LblStockCode" runat="server" Text='<%# Eval("StockCode") %>'></asp:label>
</ItemTemplate>
</asp:TemplateField>
You can even omit the Eval
on aspx and set the Text
property completely in codebehind:
If e.Row.RowType = DataControlRowType.DataRow Then
Dim row = DirectCast(e.Row.DataItem, DataRowView)
Dim lblStockCode = DirectCast(e.Row.FindControl("lblStockCode"), Label)
lblStockCode.Text = StockCodeConverter.Convert(row["StockCode"].ToString)
End If
Edit: If you want to stay with your text and also with the TemplateField
you could cast the first control in the cell which is a autogenerated DataBoundLiteralControl
when there's only text and use it's Text
property.
Dim StockCode = DirectCast(e.Row.Cells(2).Controls(0), DataBoundLiteralControl).Text
But that makes your code less readable in my opinion.