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;
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!
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)
hi
its very helpfull
_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?
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:
<asp:BoundField DataField="QuoteText" ** other attrs **/>
Code-Behind:
gridview_RowUpdating(... sender, ... e)
// e.NewValues.Count == 0 :(
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.).
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:
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.
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
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='"+.....+"'
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 umer.khan@systemsltd.com just bug me ,i ll reply with simple code i did
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.
code for rowupdating event
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
Jeff's suggestion worked like a champ. Thanks Jeff!
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
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!
Ryan's comment about OldValues didn't work on mine.
Both OldValues and NewValues are New ones in this way.
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 pankaja_shankar@ml.com
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
i had one problem that is when we click the edit button the updating template is coming but not refelected in the database
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?
How to get the values of gridview cells in
a button click event when the grid view contains both boundfields and template fields
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;
Hello,
Jeff's code it's not working when the autogeneratecolumns = true because the Collumns.Count it's always 0.
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?
Check out msdn.microsoft.com/.../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.
then what i do it is not complete
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:
www.4guysfromrolla.com/.../printPage.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.