There are 2 parts to my question. Please bear with me... just learning this stuff.
I have a GridView that allows editing, which will update a database table. Issue #1 is that I cannot seem to get the values from the GridView in my code behind. I keep getting an error. I've tried it several different ways and I'm at a total roadblock.
Here is the ASP.NET markup:
<asp:GridView ID="ItemView" runat="server"
AutoGenerateColumns="false" AllowPaging="true"
HorizontalAlign="Center"
PageSize="10" HeaderStyle-BackColor="#6f263d"
HeaderStyle-ForeColor="White" CellPadding="7" CellSpacing="0"
DataKeyNames="orderItemId" AllowSorting="True"
AlternatingRowStyle-BorderStyle="Solid" AlternatingRowStyle-BackColor="White"
AlternatingRowStyle-ForeColor="#6f263d" AlternatingRowStyle-CssClass="fancylink"
Font-Size="Small" RowStyle-BackColor="#63666A"
RowStyle-BorderStyle="None" RowStyle-ForeColor="White"
SelectedRowStyle-BackColor="#D3D0C8" SelectedRowStyle-ForeColor="Black"
Width="100%"
OnSelectedIndexChanged="ItemView_SelectedIndexChanged"
ShowHeaderWhenEmpty="false" PagerStyle-CssClass="fancylink"
PagerStyle-BackColor="#6f263d" PagerStyle-ForeColor="White"
PagerSettings-FirstPageText="First Page "
PagerSettings-Mode="NextPrevious" PagerSettings-NextPageText="Next Page"
PagerSettings-LastPageText="End" PagerSettings-PreviousPageText="Previous Page"
PagerStyle-HorizontalAlign="Center" PagerStyle-Width="20%"
OnPageIndexChanging="OnPageIndexChanging"
OnRowDataBound="ItemView_RowDataBound"
OnRowEditing="ItemView_EditRow"
OnRowUpdating ="ItemView_OnRowUpdating"
BorderStyle="None"
OnRowCancelingEdit ="ItemView_RowCancelingEdit"
OnRowDeleting="ItemView_DeleteRow"
OnSelectedIndexChanging="ItemView_OnSelectedIndexChanging"
AutoGenerateSelectButton="False">
<Columns>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbl_itemId" runat="server" Text='<%#Eval("orderItemId") %>' ReadOnly="True"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Description">
<ItemTemplate>
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 400px;">
<asp:LinkButton ID="btn_Select" runat="server" Text='<%#Eval("item") %>' ToolTip='<%# Eval("item") %>' CommandName="Select" ItemStyle-HorizontalAlign="Center" />
</div>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PO Num">
<ItemTemplate>
<asp:Label ID="lbl_poNum" runat="server" Text='<%#Eval("poNum") %>' NullDisplayText="--"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_poNum" runat="server" Text='<%#Eval("poNum") %>' Width="75px"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Amount">
<ItemTemplate>
<asp:Label ID="lbl_amount" runat="server" Text='<%#Eval("amount") %>' NullDisplayText="--"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_amount" runat="server" Text='<%#Eval("amount") %>' Width="60px"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:Label ID="lbl_quantity" runat="server" Text='<%#Eval("quantity") %>' NullDisplayText="--" ReadOnly="True"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date Ordered">
<ItemTemplate>
<asp:Label ID="lbl_ordered" runat="server" Text='<%#Eval("ordered") %>' NullDisplayText="--"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_ordered" runat="server" Text='<%#Eval("ordered") %>' Width="75px"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date Received">
<ItemTemplate>
<asp:Label ID="lbl_received" runat="server" Text='<%#Eval("received") %>' NullDisplayText="--"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_received" runat="server" Text='<%#Eval("received") %>' Width="75px"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tech Notes">
<ItemTemplate>
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 500px;">
<asp:Label ID="lbl_techNotes" runat="server" Text='<%#Eval("techNotes") %>' ToolTip='<%# Eval("techNotes") %>' NullDisplayText="--"></asp:Label>
</div>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_techNotes" runat="server" Text='<%#Eval("techNotes") %>' Width="380px"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btn_Edit" runat="server" Text="Edit" CommandName="Edit" ItemStyle-HorizontalAlign="Center"/>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="btn_Update" runat="server" Text="Update" CommandName="Update" ItemStyle-HorizontalAlign="Center" />
<asp:LinkButton ID="btn_Cancel" runat="server" Text="Cancel" CommandName="Cancel" ItemStyle-HorizontalAlign="Center" />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And in my code behind:
protected void ItemView_OnRowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = ItemView.SelectedRow;
int itemNum = Convert.ToInt16(ItemView.DataKeys[e.RowIndex].Values[0]);
string poNum = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_poNum")).Text;
string amount = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_amount")).Text;
string quantity = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_quantity")).Text;
string ordered = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_ordered")).Text;
string received = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_received")).Text;
string techNotes = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_techNotes")).Text;
string updateQuery = "UPDATE OrderItems SET ";
bool firstField = true;
if (!string.IsNullOrEmpty(poNum))
{
updateQuery += "purchaseOrderNum = @OrderNum";
firstField = false;
}
if (!string.IsNullOrEmpty(amount))
{
if (!firstField) updateQuery += ", ";
updateQuery += "itemAmt = @Amount";
firstField = false;
}
if (!string.IsNullOrEmpty(quantity))
{
if (!firstField) updateQuery += ", ";
updateQuery += "quantity = @Quantity";
firstField = false;
}
if (!string.IsNullOrEmpty(ordered))
{
if (!firstField) updateQuery += ", ";
updateQuery += "dateOrdered = @Ordered";
firstField = false;
}
if (!string.IsNullOrEmpty(received))
{
if (!firstField) updateQuery += ", ";
updateQuery += "dateReceived = @Received";
firstField = false;
}
if (!string.IsNullOrEmpty(techNotes))
{
if (!firstField) updateQuery += ", ";
updateQuery += "techNotes = @TechNotes";
}
updateQuery += "WHERE orderItemId = @ID";
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ForCustomWebApps"]))
{
using (SqlCommand cmd = new SqlCommand(updateQuery, conn))
{
cmd.Parameters.AddWithValue("@ID", id);
if (!string.IsNullOrEmpty(poNum))
cmd.Parameters.AddWithValue("@OrderNum", poNum);
if (!string.IsNullOrEmpty(amount))
cmd.Parameters.AddWithValue("@Amount", amount);
if (!string.IsNullOrEmpty(quantity))
cmd.Parameters.AddWithValue("@Quantity", quantity);
if (!string.IsNullOrEmpty(ordered))
cmd.Parameters.AddWithValue("@Ordered", ordered);
if (!string.IsNullOrEmpty(received))
cmd.Parameters.AddWithValue("@Received", received);
if (!string.IsNullOrEmpty(techNotes))
cmd.Parameters.AddWithValue("@TechNotes", techNotes);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
ItemView.EditIndex = -1;
BindGrid();
}
I have confirmed that the first 2 lines are indeed getting me the correct row (itemNum):
GridViewRow row = ItemView.SelectedRow;
int itemNum = Convert.ToInt16(ItemView.DataKeys[e.RowIndex].Values[0]);
But then it just breaks. When I run it I get:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 116: int itemNum = Convert.ToInt16(ItemView.DataKeys[e.RowIndex].Values[0]);
Line 117:
Line 118: string poNum = ((System.Web.UI.WebControls.TextBox)row.FindControl("txt_poNum")).Text;
So that's the first problem.
The second issue is that someone can edit multiple fills in the gridview row, but they don't HAVE to edit them all. They might enter a PONumber and an amount, but no techNotes or Received Date. I need an elegant way to check for empty fields for building my update statement. You can see what I've done, which is modeled off something I found on the web. Is there a better way I can do this a loop?
Thank you in advance for any help you can give me. I'm pulling my hair out!