Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the DataItem null for a GridView row "null" when trying to save changes?

So I've got this GridView on my web page. It is databound, so during the RowDataBound event this code works perfectly well:

    protected void myGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            TimecardApproval shift = (TimecardApproval)e.Row.DataItem;
        }
    }

The "shift" variable has all the data I need, works great. But then there's this code for saving the data:

    protected void btnSubmitApprovals_Click(object sender, ImageClickEventArgs e)
    {
        foreach (GridViewRow item in gvTimeCards.Rows)
        {
            TimecardApproval shift = (TimecardApproval)item.DataItem;
            // code to update the row
        }
    }

The DataItem is null! Why? Since the field is there, it seems strange that it's null. Should I be looping over something else?

like image 691
TheGerm Avatar asked Nov 08 '12 23:11

TheGerm


3 Answers

I understand you may want to have intellisense by casting DataItem to TimeCardApproval. You can do this instead. Use the DataKeyNames to store the Primary Key of each row which should be TimecardApprovalID and in your code access the primary key and use it to get the original item

foreach (GridViewRow item in gvTimeCards.Rows)
{
   //get the ID of the TimeApproval for each row
   string id = gvDocs.DataKeys[item.RowIndex].Value.ToString();
   //string id = ((HiddenField) item.FindControl("IDHiddenField")).Value;
   //string id = item.Cells[0].Text;

   //use the ID or get TimeCardApproval object from DB    
   TimecardApproval shift = MyDB.GetTimeCardApproval(id);

}

Setting the Keys

<asp:GridView ID="gvTimeCards" DataKeyNames="TimecardApprovalID">
</asp:GridView>
like image 136
codingbiz Avatar answered Mar 25 '23 16:03

codingbiz


Maybe, this help you
Grid column:

<asp:TemplateField HeaderText="Item ID">
<ItemTemplate>
    <asp:Label runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Id") %>'/>
    <asp:HiddenField runat="server" ID="hfDataItem" Value='<%# JsonConvert.SerializeObject(Container.DataItem) %>'/>
</ItemTemplate></asp:TemplateField>

Code behind:

    protected void btApply_OnClick(object sender, EventArgs e)
    {
        var rows = (from GridViewRow row in gvResult.Rows
            where row.RowType == DataControlRowType.DataRow
            let dataItem = (HiddenField) row.FindControl("hfDataItem")
            select JsonConvert.DeserializeObject<ResultGridRowItem>(dataItem.Value));

    }
like image 41
Spoke Avatar answered Mar 25 '23 18:03

Spoke


The gridview databind event fires before the button click. Sounds wierd but that's asp.net page life cycle craziness. Try using your code in gridview RowUpdating or RowUpdated event.

like image 20
boruchsiper Avatar answered Mar 25 '23 18:03

boruchsiper