Reputation: 555
I have a GridView that needs to have an editable column in each row. I have declared it as shown below.
<asp:GridView ID="TestGrid" runat="server" AllowPaging="true" SkinID="GridViewNew" AllowSorting="False"
OnRowDataBound="GridViewTest_RowDataBound" EnableViewState="True"
OnRowUpdating="GridViewTest_OnRowUpdating" OnRowEditing="GridViewTest_OnRowEditing" OnRowCancelingEdit="GridViewTest_OnRowCancelingEdit"
AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowEditButton="True" CausesValidation="False" />
<asp:BoundField DataField="Client" HeaderText="Client" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="Stock" HeaderText="Stock" InsertVisible="False" ReadOnly="True" />
<asp:TemplateField HeaderText="DutyStatus" InsertVisible="False" >
<ItemTemplate>
<asp:Label ID="standLbl" runat="server"><%#Eval("DutyStatus").ToString().Trim() %></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DdlDutyStatus" runat="server"
DataTextField="DutyStatus"
DataValueField="DutyStatus">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Percentage" InsertVisible="False" SortExpression="enhanced">
<ItemTemplate>
<asp:Label ID="enhLbl" runat="server"><%#Eval("percentage").ToString().Trim() %></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TbPercentage" runat="server" Text='<%#Eval("percentage").ToString().Trim()%>' class="edit-field"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The Data is displayed as it should be. The problem arises when trying to edit the Percentage value. Clicking 'Update' works fine and the editable TextBox within the cell is displayed, however when the value has been modified and 'Update' is clicked, when the GridViewTest_OnRowUpdating
method is hit, the object sender and GridViewUpdateEventArgs
are both empty. The method is defined as below.
protected void GridViewTest_OnRowUpdating(object ASender, GridViewUpdateEventArgs AE)
{
PerformDataTableUpdate(ref TestGrid, AE);
}
In the above method; object ASender has no rows, GridViewUpdateEventArgs
AE properties are all empty (Keys, NewValues, OlValues etc).
I have ensured that the GridView is not getting rebound in Page_Load or anywhere else (it is empty when it enters and leaves Page_load
and still empty when it hits GridViewTest_OnRowUpdating
on update postback).
Any help would be much appreciated.
Upvotes: 2
Views: 1178
Reputation: 10565
When updating values using GridView, you need to set the DataKeyNames
property. Once this is specified Gridview uses the keys to uniquely identify which rows needs to be updated/deleted
DataKeyNames
is usually set to the Primary Keys of the table but we are not bound to do that always.
MSDN Says:
You must set the DataKeyNames property in order for the automatic update and delete features of the GridView control to work. The values of these key fields are passed to the data source control in order to specify the row to update or delete
EDIT::
1.) GridViewUpdateEventArgs AE properties are all empty (Keys, NewValues, OlValues etc)
Now there's a condition that GridView will only use the DatakeyNames
and populate the Old
and New
values ONLY when data is bound using DataSourceID
property. This is by design.
2.) object ASender has no rows
I suspect this happening because of data binding to gridview not being done in a correct way.
Below are some common discussions/resolutions around this issue::
1.) Since data is bind to gridview at runtime, make sure you bind it as below:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = ds; // appropriate data source here
GridView1.DataBind();
}
}
Why DataBind() the above way? ::
After clicking the "Update" button,
Page_Load()
event gets fired beforeOnRowUpdating()
event. Therefore if you MISS using theIsPostback
property,GridView
is getting bound( Refreshed ) again with the Original values(i.e. OldValues)
This is required so that in our onRowUpdating
event we get the New values we submitted earlier.
2.) Getting values from Rows:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = (GridViewRow)GridView1.Rows[e.RowIndex];
TextBox FirstName= (TextBox)row.FindControl("txtFirstName");
}
Upvotes: 3