C# – Get Item from GridViewRow ASP.NET

asp.netcgridview

I have a GridView which I Bind a DataSource to it from a SQL Database, the grid has a column with a checkbox in it so I can "select" a few Item in it (Rows actually). What I want here is to do some updates on the Item in each selected rows, but after some search I can't find how to access the Item in a Row, I though DataItem would work, but it's giving me a Null.

Edit: To make it short, I have a GridView which is built from a DataSource, so basically, each rows represent an Object, when I have a checkbox checked in one of the rows, I want to be able to grab the Object related to that Row, what is the easiest way to achieve that?

The DataBinding on Page_Load:

  if (!Page.IsPostBack)
    {
        gvUnusedAccessories.DataSource = currentContext.Items.OfType<Accessory>().Where(ac => ac.Item_Parent_Id == ((PhoneLine)currentItem).Parent.Item_Id);
        gvUnusedAccessories.AutoGenerateColumns = false;
        gvUnusedAccessories.DataBind();
    }

The event when I press the Update Button, It actually browse the rows and if the row has a checked box it's gonna do the update:

protected void btnAddToMobile_Click(object sender, EventArgs e)
{
    foreach (GridViewRow row in gvUnusedAccessories.Rows)
    {
        if(((CheckBox)row.FindControl("chkSelect")).Checked)
        {
            ((Accessory)row.DataItem).PhoneLine_Id = currentItem.Item_Id;
        }
    }
}

And here's my GridView in the .aspx :

 <asp:GridView ID="gvUnusedAccessories" runat="server">
    <Columns>
        <asp:CommandField ShowSelectButton="True" />
        <asp:TemplateField HeaderText="Select">
            <ItemTemplate >
                <asp:CheckBox ID="chkSelect" runat="server" AutoPostBack="True"/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Item_Id" HeaderText="ID" ReadOnly="True"/>
        <asp:BoundField DataField="Item_Name" HeaderText="Name" ReadOnly="True"/>  
        <asp:BoundField DataField="AccessoryModel" HeaderText="Modèle" ReadOnly="True"/>
        <asp:BoundField DataField="AccessoryBrand" HeaderText="Marque" ReadOnly="True"/>
    </Columns>
</asp:GridView>

Any hint on how to access the Object contained inside a Row?
I know I could actually get the ID and then do a SQL request to my DB, but it seems to be a bit heavy and there must be a better solution.

Best Answer

Unless you're storing the DataSource in ViewState or session once the databinding is done you lose the data source. The DataItem will always be null unless you do this. Because of this I often find myself storing the data source in view state. Of course this means your page size is going to get bigger. The other option as you stated is to requery the data source with some sort of primary key. Depending on your needs I can't say which option is better. I tend to lean towards view state rather than a second DB call since that can be an expensive call to make