El controlador de eventos GridView RowDataBound no encuentra el contenido de las celdas de GridView

Tengo lo siguiente 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 Número de inventario 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 Número de inventario 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?

preguntado el 28 de agosto de 12 a las 14:08

2 Respuestas

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

en aspx:

<asp:TemplateField HeaderText="Stock Code">
    <ItemTemplate>
        <asp:Label Id="LblStockCode" runat="server" Text='<%# Eval("StockCode") %>'></asp:label>
    </ItemTemplate>
</asp:TemplateField>

Incluso puede omitir el 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

Editar: 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 propiedad.

Dim StockCode = DirectCast(e.Row.Cells(2).Controls(0), DataBoundLiteralControl).Text

But that makes your code less readable in my opinion.

Respondido 28 ago 12, 14:08

Ok thanks I will try your solution! Anyway may you explain me why it does not find the values? The DataBind happens later? - CiccioMiami

@CiccioMiami: Because a TemplateFieldcontains controls that you can access via their ID's. If you don't want to use it you can use a BoundField, Entonces el Text property of the cell would not be empty. - Tim Schmelter

I didn't know that, the web is full of examples about rowdatabound but none of them in the scope of this situation! Thanks for the explanation as well! - CiccioMiami

I think in GridView RowDataBound Event as the Binding is still in process you are not getting any Value...I would suggest you to use "DataRowView"

DataRowView drv = (DataRowView)e.Row.DataItem;
e.Row.Cells(2).Text = drv["StockCode"].ToString();

Respondido 28 ago 12, 14:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.