Обработчик событий GridView RowDataBound не находит содержимое ячеек GridView

У меня есть следующий GridView, который имеет как DataSource 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>

Который отображается правильно и с правильными значениями.

Теперь я хотел бы изменить на лету поле StockCode, и для этого в моем коде есть:

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

Но ячейки данных, соответствующие StockCode, пусты. Теперь я попытался отладить, и по какой-то причине код находит только значение строки заголовка. Значения других строк — string.Empty или &nsbp. Может ли это зависеть от списка как источника данных?


person CiccioMiami    schedule 28.08.2012    source источник


Ответы (2)


Вместо этого используйте элементы управления ASP.NET, например Labels< /а>:

If e.Row.RowType = DataControlRowType.DataRow Then
     Dim lblStockCode = DirectCast(e.Row.FindControl("lblStockCode"), Label)
    lblStockCode.Text = StockCodeConverter.Convert(lblStockCode.Text)
End If

на аспкс:

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

Вы даже можете опустить Eval в aspx и полностью установить свойство Text в отделенном коде:

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

Изменить. Если вы хотите сохранить свой текст, а также использовать TemplateField, вы можете применить первый элемент управления в ячейке, который представляет собой автоматически сгенерированный DataBoundLiteralControl, когда есть только текст, и используйте его свойство Text.

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

Но это делает ваш код менее читаемым, на мой взгляд.

person Tim Schmelter    schedule 28.08.2012
comment
Хорошо, спасибо, я попробую ваше решение! В любом случае, можете ли вы объяснить мне, почему он не находит значения? DataBind происходит позже? - person CiccioMiami; 28.08.2012
comment
@CiccioMiami: Потому что элементы управления TemplateFieldcontains, к которым вы можете получить доступ через их идентификаторы. Если вы не хотите его использовать, вы можете использовать BoundField, тогда свойство Text ячейки не будет пустым. - person Tim Schmelter; 28.08.2012
comment
Я этого не знал, в Интернете полно примеров с rowdatabound, но ни один из них не относится к этой ситуации! Спасибо и за объяснение! - person CiccioMiami; 28.08.2012

Я думаю, что в событии GridView RowDataBound, поскольку привязка все еще находится в процессе, вы не получаете никакого значения... Я бы предложил вам использовать "DataRowView"

DataRowView drv = (DataRowView)e.Row.DataItem;
e.Row.Cells(2).Text = drv["StockCode"].ToString();
person Amol Kolekar    schedule 28.08.2012