DataBinding in ASP.NET 2.0 and the RowUpdating event

For a while now I’m trying to figure out why my method, triggered by the GridView.RowUpdating event, doesn’t work as all samples say it should do. All samples of course assume you’re doing everything in your .aspx page, but I have to do everything in my code-behind, because on forehand I don’t know what I’ll be binding to my GridView. Check out what I’m trying to do, maybe you can help?


First, I load up some data:



DataSet ds = new DataSet();


SqlConnection con = new SqlConnection(“somestring”);


SqlCommand cmd = new SqlCommand(“select * from sometable”, con);


SqlDataAdapter adap = new SqlDataAdapter(cmd);


adap.Fill(ds);


After that, I’m doing some work to make my GridView look beautifull, adding all columns by hand. But for this demo, I’ll show you the simple version, that also doesn’t work 🙂
Let’s bind the data to our GridView and have it autogenerate our columns, as well as an edit button.



GridView1.AutoGenerateColumns = true;


GridView1.AutoGenerateEditButton = true;


 


GridView1.DataSource = ds;


GridView1.DataBind();


Now I’ve tried a lot of places to setup subscription to the events. Currently I’m in the OnInit method, but it doesn’t matter where you place this code.



protected override void OnInit(EventArgs e)


{


  base.OnInit(e);


  GridView1.RowUpdating += new GridViewUpdateEventHandler(GridView1_RowUpdating);


  GridView1.RowUpdated += new GridViewUpdatedEventHandler(GridView1_RowUpdated);


  GridView1.RowEditing += new GridViewEditEventHandler(GridView1_RowEditing);   


}


So now everything’s setup, let’s create a method for the RowEditing event.



void GridView1_RowEditing(object sender, GridViewEditEventArgs e)


{


  GridView1.EditIndex = e.NewEditIndex;


  GridView1.DataBind();


}


Been there, done that… Okay, now the part that doesn’t work!



void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)


{


  // This method is never even touched!


}


 


void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)


{


  // e.Keys.Count == 0


  // e.NewValues.Count == 0


  // e.OldValues.Count == 0


}


When we edit a row in our GridView and press the “Update” button, at some time it’s received in the RowUpdating method. But as I noted in the comments in that method, some collections that should contain the columns (names, old values and new values) are always empty. Always. And the RowUpdated method is never even touched!!!


Okay, so I’ve read on the ASP.NET Forums that I need to use a DataSource control. For example a SqlDataSource, which is automatically added to your WebForm if you drag-n-drop your way around Visual Studio 2005. The problem is, I’d very much like to do so, if ASP.NET 2.0 requires this. But I can’t set a DataSource property or anything on the SqlDataSource!!!


So if you have any solution to my problem… I probably have to read the cells on the GridView of the selected row, find the controls, get the values from those and insert those into my DataSet. Which means I won’t make my 70% code reduction Microsoft has always promised me. Bah!

You may also like...

38 Responses

  1. Check out if you are using Template Fields in your GridView. In that case, you cannot use e.NewValues. You need to do a findcontrol of the TextBox or Label in the TemplateField and typecast it into a dynamic Textbox or label and get the value from it.

    The e.NewValues works only with Bound Columns.

    Thanks.

  2. kg says:

    Did you figure this out? I’m using templatefields. And the event is not firing.

  3. I should post that, shouldn’t I?

    It isn’t possible though, and I forgot what I actually used to get the values. If I’m not mistaken, I’m using the Request object to get the values myself. If you’re really interested, I could look up the code. Send me a mail via my contact form. (mail button top-left corner of this page)

  4. prasad says:

    hi
    its very helpfull

  5. WebColin says:

    _rowUpdating event will not firing, when dynamic create GridView. not only findcontrol but also no value e.NewVlaues too. is that any other way to get the values from GridView?

  6. Lee says:

    I’m having a similar problem. When using a GridView whose DataSource is set manually in code-behind, e.NewValues contains nothing (even with BoundFields).

    Markup:

    Code-Behind:
    gridview_RowUpdating(… sender, … e)
    {
    // e.NewValues.Count == 0 🙁
    }

  7. Lee says:

    My current workaround is to have the user redirected to an edit page when attempting to edit a GridView row. This isn’t ideal, but frankly it allows me add customizable edit code (large TextBox, etc.).

  8. Jeff says:

    It’s actually fairly easy to get the info you want once you know the trick. When dynamically binding to the GridView, use the following code in the RowEditing event:

    GridView gv = (GridView)sender;
    gv.EditIndex = e.NewEditIndex;
    gv.DataBind();

    To populate the NewValues collection, put the following code in the RowUpdating event:

    GridView gv = (GridView)sender;
    for (int i = 0; i < gridView.Columns.Count; i++)
    {
    DataControlFieldCell cell = gv.Rows[e.RowIndex].Cells[i] as DataControlFieldCell;
    gv.Columns[i].ExtractValuesFromCell(e.NewValues, cell, DataControlRowState.Edit, true);
    }

    Then you can use the NewValues collection as you would if the GridView was bound to a SqlDataSource. This works with both bound fields and template fields.

  9. Shashanka says:

    Hi Jeff,
    I have a similar problem too. I have GridView with that gets data from table (using a dynamic sql….creating Views on fly). So I donot know the table structure thats going to bind with the GridView.
    But anyways the first three columns are known, the last among which is date.
    I have created a TemplateField (Say DataGridCalenderControl)implementing ITemplate interface.
    Unfortunately I am not able to CAST the DataGridCalenderControl to DataControlFieldCell
    DO you have any suggestions
    Thanks

  10. priyak says:

    when i update a grid view i dint know how to assign it to a variable……
    because i can update a sqlserver database in update command where i need to give
    update table-anme set fields='”+…..+”‘

  11. Umer says:

    jeff?
    i did that u posted ? but its not working
    i m not getting any value? i m using itemtemplete/edidttemplete , i m stuck here for many days, i cant get values on text ( after we click update)
    and how could we call updated? rahter than updating
    u can email at [email protected] just bug me ,i ll reply with simple code i did

  12. Chuck Sndyer says:

    Thanks for the information. The databind in the row editing event did the trick. Trying to enable/disable a control depending on the user rights.

    Thanks.

  13. jigna says:

    code for rowupdating event

  14. Ray says:

    Be aware with what jeff posted, it will function okay but not as okay it should be, you need to know that null and empty strings will give you big headeach in the new collection 🙂

  15. ap says:

    Hi,

    it is not working for me, im trying to read the value of a bounded field during edit mode. i tried the ExtractValuesFromCell but getting thye following in the watcher: Expression has been evaluated and has no value. what should i do?
    thank

  16. billb says:

    Jeff’s suggestion worked like a champ. Thanks Jeff!

  17. Ryan says:

    Jeffs comment works superb for NewValues, I guessed a way to extend it to fill OldValues, mind you, it didn’t take much imagination:

    gv.Columns[i].ExtractValuesFromCell(e.OldValues, cell, DataControlRowState.Edit, true);

    Cheers Jeff

  18. irfan says:

    jeffs comment did not work! 🙁 yes i get some values to e.NewValues but unfortunately they are not the NEW ones. they are the old ones. I am stuck here!

  19. Annie says:

    Ryan’s comment about OldValues didn’t work on mine.
    Both OldValues and NewValues are New ones in this way.

  20. Pankaja says:

    I have a gridview in which I have 8 templated field columns which are dynamically created and has only OnDataBinding event attached to them. Besides I have 4 bound field that were created at design time for the page which are sortable. When I sort, even though I remove the templated columns and re-add them still the grid shows only the 4 bound fields and everything else is empty (i.e. the data rows). This is I think due to the OnDataBinding not getting fired for the templated fields on sort. Any help is appreciated, as soon as you can, since I have a monday deadline (12/10/2007). Thanks and you can respond to [email protected]

  21. Matt says:

    I just used this where my template field is a lable

    GridView grd = (GridView) sender;
    Label lbl = (Label) grd.Rows[e.RowIndex].FindControl(“lblempIDe”);

  22. Matt says:

    I just used this where my template field is a lable

    GridView grd = (GridView) sender;
    Label lbl = (Label) grd.Rows[e.RowIndex].FindControl(“lblempIDe”);

    now use the

    lbl.Text

    to find the value

  23. bala says:

    i had one problem that is when we click the edit button the updating template is coming but not refelected in the database

  24. Piter says:

    Hi!

    I have problem.
    i’s my function delegate.

    void GV_RowUpdated(object sender, GridViewUpdatedEventArgs e)
    {
    rowID = e.RowIndex;

    wartoscId = ds.Tables[nazwa_tabeli].Rows[rowID][“Id”].ToString();
    GridViewRow row = GV.Rows[rowID];

    drCurrent = dt.NewRow();
    drCurrent = dt.Rows.Find(wartoscId);
    drCurrent.BeginEdit();
    drCurrent[“Pole1”] = ((TextBox)(row.Cells[2].Controls[0])).Text;
    drCurrent[“Pole2”] = ((TextBox)((GridView)sender).Rows[e.RowIndex].Cells[3].Controls[0]).Text;
    drCurrent.EndEdit();

    OleDbCommandBuilder objCommandBuilder = new OleDbCommandBuilder(adapter);
    adapter.Update(ds, nazwa_tabeli);

    GV.EditIndex = -1;
    GV.DataBind();

    }

    It’s ok but value drCurrent[“Pole1”] it’S STILL old.
    How I can get new value?

  25. malik says:

    How to get the values of gridview cells in
    a button click event when the grid view contains both boundfields and template fields

  26. I’m also getting the old values in the newValues when using the code posted by Jeff. Has anyone found a resolution for this?

    Thanks.

  27. I found the answer for my problem, newValues equalling the oldValues. Check your postbacks! If you are binding the gridview on page load, make sure that you are only doing it when not isPostBack. I found that I was losing my newValues due to a postback which in turn rebound my gridview and overwrote my data.

  28. baski says:

    To get the modified (edit) values in Row Updating event in GridView

    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {

    GridViewRow grv = GridView1.Rows[e.RowIndex];

    int intPhoneId = Convert.ToInt32(((TextBox)(grv.Cells[1].Controls[0])).Text);
    string strPname= ((TextBox)(grv.Cells[2].Controls[0])).Text;
    string strMname = ((TextBox)(grv.Cells[3].Controls[0])).Text;
    string strCname = ((TextBox)(grv.Cells[4].Controls[0])).Text;
    }

  29. Marius says:

    Hello,

    Jeff’s code it’s not working when the autogeneratecolumns = true because the Collumns.Count it’s always 0.

  30. maurizio says:

    I i’m from italy.
    real intresting this discution on gridview.rowupdating.

    i have a strange problem. i’m not use sqldatasource,
    just write by myself update method.
    i use template field and with findcontrol i get the right value BUT (and made me crazy) the rowupdating event FIRE two TIME!!!!! so second time all object is NOTHING and i have server/error.
    anyone can explain me WHY this event fire two times?

  31. Dave Amour says:

    Check out http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowupdating.aspx

    It says that:

    The Keys, OldValues and NewValues collections are automatically populated only when the GridView control is bound to data by using the DataSourceID property.

  32. yasir says:

    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)

    {

    GridViewRow grv = GridView1.Rows[e.RowIndex];

    int intPhoneId = Convert.ToInt32(((TextBox)(grv.Cells[1].Controls[0])).Text);

    string strPname= ((TextBox)(grv.Cells[2].Controls[0])).Text;

    string strMname = ((TextBox)(grv.Cells[3].Controls[0])).Text;

    string strCname = ((TextBox)(grv.Cells[4].Controls[0])).Text;

    then what i do it is not complete

    }

  33. Jimbo says:

    I have found a VERY similar situation wherein the Update and Delete methods of the SQLDataSource are never invoked by the GridView when the GridView is created dynamically. Subsequently, the RowUpdated or RowDeleted events should of course be called, but as you noted, no events after the action event occur (presumably because the action event didn’t happen.

    This page gives an excellent rundown of the flow of this operation and how it is supposed to work:
    http://www.4guysfromrolla.com/demos/printPage.aspx?path=/articles/062007-1.aspx
    Unfortunately, it seems it doesn’t quite work that way with dynamically generated GridViews.

    Hopefully this will get you one step closer to the answer. If you come up with it, please post it. This has been eating my lunch for a week.

  34. Jesse says:

    I have a grid bound to an object datasource.
    Some of my columns are template fields.
    I could not get the values from the gridview in my codebehind code but thanks to Matt it worked.

    Matt’s posting below (in this posting) worked for me.

    Here is his post:::::::::::::::::::::::
    I just used this where my template field is a lable

    GridView grd = (GridView) sender;

    Label lbl = (Label) grd.Rows[e.RowIndex].FindControl(“lblempIDe”);

    now use the

    lbl.Text

    to find the value

  35. Houses and cars are quite expensive and not everyone is able to buy it. Nevertheless, business loans are created to support people in such hard situations.

  36. payal says:

    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
    msaccess.Open();
    //OleDbCommand cmd = new OleDbCommand(“update Table2 set name=@mname,city=@mcity where srno=@msrno”,msaccess);
    OleDbCommand cmd = new OleDbCommand(“update Table2 set srno=@msrno,name=@mname,city=@mcity where srno=@msrno”, msaccess);
    cmd.Parameters.Add(new OleDbParameter(“@msrno”, OleDbType.Integer));
    //cmd.Parameters[“@msrno”].Value = Convert.ToInt32(((TextBox)(GridView1.Rows[e.RowIndex].Cells[1].Controls[0])).Text);

    cmd.Parameters[“@msrno”].Value =Convert.ToInt32 ((GridView1.Rows[e.RowIndex].Cells[0].Text));

    cmd.Parameters.Add(new OleDbParameter(“@mname”, OleDbType.VarChar));
    cmd.Parameters[“@mname”].Value=((TextBox)(GridView1.Rows[e.RowIndex].Cells[1].Controls[0])).Text;

    cmd.Parameters.Add(new OleDbParameter(“@mcity”, OleDbType.VarChar));
    cmd.Parameters[“@mcity”].Value= ((TextBox)(GridView1.Rows[e.RowIndex].Cells[2].Controls[0])).Text;

    //cmd.Connection.Open();

    cmd.ExecuteNonQuery();
    // cmd.Connection.Close();
    msaccess.Close();
    GridView1.EditIndex = -1;
    bindgrid();
    //GridView1.DataBind();

    }

  37. buy an essay says:

    It’s not so simple to bring a not bad written essay, preferably if you are engaged. I give advice you to define buy essays and to be spare from disbelief that your work will be done by writing service

  38. credit loans says:

    I had got a dream to begin my own business, nevertheless I did not earn enough amount of money to do that. Thank heaven my colleague told to use the loan. Therefore I took the secured loan and realized my desire.

Leave a Reply

Your email address will not be published. Required fields are marked *