开发者

Accessing the data or dataItem used to bind a gridview

I have a gridview for which I programmatically set the datasource and databind it to a collection of objects. For each row that is created I then use different methods in the fields to extract the relevant information from the object like this one:

<asp:TemplateField HeaderText="Aliases">
<ItemTemplate>
<%# ( (MyItem)Container.DataItem).Aliases.ToString() %>
</ItemTemplate>
</asp:TemplateField>

My problem is that in the OnRowDeleting method I would preferably like to be able to access that DataItem using e g MyGridView.Rows[e.RowIndex].DataItem or in other way. But I can’t find how to configure the Gridview to retain the DataItem. Is it possible to access the DataItem used and how would I configure it to do it? If that’s not possible can I access the values that are bind by the methods? Or do I have to go with plan B and rewrite the datasou开发者_运维知识库rce object collection to a datatable and then use datakeysnames?


MyGridView.Rows[e.RowIndex].DataItem should generally work but I guess that you are probably relying the view-state for retaining grid data on post-backs. In such case, you will get the DataItem property as NULL.

Work-around can be to always re-bind the grid with actual data in each postback early in page life cycle (say page_load).

However, in your case, you can very well use DataKeyNames. Contrary to your belief, you don't need a DataTable for this property to work. For example, if your class has property named ItemId indicating the key for your object then you can use DataKeyNames="ItemId" in the markup and refer it in OnRowDeleting using Keys property of event arguments.


According to MSDN:

"The DataItem property is only available during and after the RowDataBound event of a GridView control."

Therefore, access the DataItem in the RowDataBound event:

Lets say you bind a List(Of Vehicle) to the grid:

Dim vehicles As List(Of Vehicle) = Vehicle.GetAll()
gvVehicles.DataSource = vehicles
gvVehicles.DataBind()

In the RowDataBound event access the DataItem:

Protected Sub gvVehicles_RowDataBound(sender As Object, e As GridViewRowEventArgs)

    If e.Row.RowType = DataControlRowType.DataRow Then
       Dim veh As Vehicle = TryCast(e.Row.DataItem, Vehicle)
       If Not veh Is Nothing Then
            Dim chkBox As CheckBox = CType(e.Row.FindControl("chkSelect"), CheckBox)
                chkBox.Checked = True
       End If
    End If
End Sub


I'm aware this is very dated question at this point - however, I've just run into a similar issue and none of these answers resolved the issue; so I figured I'd post an alternative solution. In my scenario, the issue was on the OnSelectedIndexChanged event. So, it should theoretically hold true for OnRowDeleting but not necessarily on OnRowDeleted (depending on where exactly in the process the row is deleted).

My solution was to simply add a HiddenField for the data that I didn't want to be visible in the GridView, for example:

        <asp:GridView ID="gvTutorGroups" runat="server" AutoGenerateColumns="False" DataSourceID="sqlTutorGroups" DataKeyNames="TTGP_Group_Code" AllowPaging="True" PageSize="8" EmptyDataText="You have no tutor groups to display." Style="margin: 0 auto; width: 870px;" OnRowDataBound="gvTutorGroups_RowDataBound" OnSelectedIndexChanged="gvTutorGroups_SelectedIndexChanged">
            <Columns>
                <asp:TemplateField >
                    <ItemTemplate>
                        <asp:HiddenField runat="server" ID="hfTTGPISN" Value="<%# Eval("TTGP_ISN") %>" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="TTGP_Group_Code" HeaderText="TG Code" />
                <asp:BoundField DataField="PRPH_Title" HeaderText="Name" />
                <asp:BoundField DataField="TTGP_Start_Date" HeaderText="Start Date" DataFormatString="{0:d}" />
                <asp:BoundField DataField="TTGP_End_Date" HeaderText="End Date" DataFormatString="{0:d}" />
            </Columns>
        </asp:GridView>

Then I just used the FindControl method to access that field, like so:

protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
    foreach (GridViewRow row in gvTutorGroups.Rows)
    {
        if (row.RowIndex == gvTutorGroups.SelectedIndex)
        {
            row.CssClass = "rowSelected";

            DataRowView dataItem = (DataRowView)row.DataItem;
            HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn");
            hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
        }
        else
        {
            row.CssClass = "";
        }
    }
}

It's not an ideal solution, but it works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜