Greetings all,
I'm a C# intermediate at best, so forgive any ignorance display in the forthcoming.
I'm using a DataGridView bound to a DataSet of database query results. I'm trying to handle a pretty common operation of updating the database when a grid cell changes. I have it all working except for one thing, that I can seem to understand. I'm using the cellEndEdit event to trigger my update to the database, which works great...sometimes.
It seems that, although the event fires every time I leave the cell after an edit, the dataset it only updated when I actually click with the mouse outside the edited cell. So, if I edit a cell and then click somewhere else, the event fires, the dataset gets updated, and hence, the database gets updated every time; however, if I edit a cell and then hit "enter" or tab out of the cell, the event still fires, but the dataset is not actually updated, and therefore the database is not updated.
Here's the operative code with comments:
// This is the event handler method
void dgHostsCellChanged(object sender, DataGridViewCellEventArgs e)
{
// If you guys know a better way to set these values, I'm all ears
string newVal = this.dgHosts.Rows[e.RowIndex].Cells[e.ColumnIndex].FormattedValue.ToString();
string column = this.dgHosts.Columns[e.ColumnIndex].Name;
string pkey = this.dgHosts.Rows[e.RowIndex].Cells[0].FormattedValue.ToString();
// dsHosts is my dataset which gets loaded in a different method. It's a public
// member variable of the MainForm class.
// db is my custom database object.
dsHosts = db.updateDSCell(dsHosts, "hosts", e.RowIndex, e.ColumnIndex, newVal);
// My dbms is PostgreSQL, so I have to handle the boolean datatype a little
// to make it compatible with the db.
switch (newVal)
{
case "True":
newVal = "t";
break;
case "False":
newVal = "f";
break;
}
// my update statement
string updateSQL = "UPDATE host SET " + column + "='" + newVal + "' WHERE host_id=" + pkey;
// as I mentioned, I'm using PostgreSQL, so Npgsql is the connector
NpgsqlCommand command = new NpgsqlCommand(updateSQL);
// daHosts is my adapter
daHosts.UpdateCommand = command;
daHosts.Update(dsHosts, "hosts");
}
// this is the updateDSCell method
public DataSet updateDSCell(DataSet ds, string tableName, int rowIndex, int colIndex, string newVal)
{
ds.Tables[tableName].Rows[rowIndex][colIndex] = newVal;
return ds;
}
Thanks.
Loading
theLizardPosted Mar 11, 2010, 4:29 PM
newVal = (newVal == "True" ? t : f);
this eliminates the switch statement.
If you have been following my posts to Georgios questions you will understand why I do not use grid views as data bound controls, way too many of these types of issues, it is best to handle. I would prefer to manually execute an update statement either on click of a button for the current row or when all edits have been done for the whole grid without using the cellEndEdit event, you are guaranteed (other than unknown errors with db or system) that the update will take place id done manually.
Anyway this is just my opinion using methods I know work in these situations.
Romeo SolisPosted Mar 11, 2010, 11:17 AM
// Divelements.SandGrid.GridRow is the Grids row property, I call my variable looseFocus and set is to the grids property of selected element at row 0
Divelements.SandGrid.GridRow looseFocus = gridView.SelectedElements[0] as Divelements.SandGrid.GridRow;
//if condition
if (looseFocus.NextVisibleRow != null)
//select the row 0 , NextVisibleRow
gridView.SelectRow(looseFocus.NextVisibleRow);
Let me know if that helps you guys
Romeo SolisPosted Mar 11, 2010, 9:56 AM
One of my Ideas for a fix around is before apply click event for it to set focus on a another element such as the apply button itself this way the cell would lose focus and data inside that field will update to collection/database.
JoanPosted Mar 11, 2010, 5:04 AM
The dataset it only updated when I actually click with the mouse outside the edited cell. So, if I edit a cell and then click somewhere else, the event fires, the dataset gets updated, and hence, the database gets updated every time; however, if I edit a cell and then hit "enter" or tab out of the cell, the event still fires, but the dataset is not actually updated, and therefore the database is not updated.
My code:
void grvSetupGrid_CellEndEdit(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
try
{
//Here the e.Row.DataBoundItem is NULL if I click Enter....
BL.Setup.EntityBase entity = e.Row.DataBoundItem as BL.Setup.EntityBase;
if (entity != null)
{
if (entity.PKID > 0)
ItemUpdated(this, e.Row.DataBoundItem);
else
{
int pkid = ItemCreated(this, e.Row.DataBoundItem);
PropertyInfo pinfo =
e.Row.DataBoundItem.GetType().GetProperties().First(p => p.Name == "PKID") != null ?
e.Row.DataBoundItem.GetType().GetProperty("PKID") : null;
if (pinfo != null)
{
pinfo.GetSetMethod().Invoke(e.Row.DataBoundItem, new object[] { pkid });
}
}
}
}
catch (Exception ex)
{
ShowError(ex);
}
}
How can I have the correct data in the DataBoundItem?
Thanks
Michael LesliePosted Dec 28, 2008, 1:02 PM
If you haven't solved this already..
adding a call to dgHosts.EndEdit() before you get the values should give you the latest values.