Reputation: 334
I've been searching a while for some kind of a mechanism that would allow to detect whenever a DataGridViewRow
of a DataGridView
changed, once that DataGridView
doesn't have a straightforward way to do this. And I've made this implementation
public partial class MyDatagrid : DataGridView
{
public event EventHandler<RowChangingArgs> RowUpdating;
public MyDatagrid()
{
InitializeComponent();
this.CellBeginEdit += OnCellBeginEdit;
}
private DataGridViewRow oldRow;
private int currentRow;
private void OnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs args)
{
if(oldRow == null || currentRow != args.RowIndex)
{
if(currentRow != args.RowIndex && oldRow != null)
{
var newRow = this.Rows[args.RowIndex];
foreach (var cell in oldRow.Cells)
{
foreach (var cell1 in newRow.Cells.Cast<object>().Where(cell1 => !cell.Equals(cell1)))
{
if(RowUpdating!= null)
RowUpdating.Invoke(this, new RowChangingArgs { OldRow = oldRow, NewRow = newRow});
oldRow.Dispose();
goto called;
}
}
}
called:
oldRow = this.Rows[args.RowIndex].Clone() as DataGridViewRow;
currentRow = args.RowIndex;
}
}
public class RowChangingArgs : EventArgs
{
public DataGridViewRow OldRow { get; set; }
public DataGridViewRow NewRow { get; set; }
}
}
Example:
User edits row 1 and column 1, keeps by editing n columns from same row.
User starts editing other row. Fire event with row 1 old content and row 1 new content.
Is this a good way of doing this, or did I miss something?
Upvotes: 0
Views: 15670
Reputation: 1408
Well you can use This which is more faster than other. Use CellEndEdit Event of The DataGridView
private void datagridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
updateCounter();
}
Upvotes: 0
Reputation: 48129
Another option... If your data is coming from a "DataTable" or "DataView" (such as a queried result from a backend), a grid's bound data source could be of a DataView.
If this is the case, you could always have it directly from event handlers at the table control management via it's columnChanging or columnChanged events... whichever you are looking for (pre/post changed value).
If so, at the table level, after the data is queried and populated for the grid population, you could then...
YourDataTable.ColumnChanging += MyColumnChanging;
then have a method...
private void MyColumnChanging(object sender, DataColumnChangeEventArgs e)
{
// just to enforce column name representation, forcing to lower
string colName = e.Column.ColumnName.ToLower();
// e.Row has the row that had the change for you to work with, validate, etc...
switch (colName)
{
case "yourcolumnfieldx":
doSomething;
break;
case "anotherfield":
doSomethingElse;
break;
}
}
Upvotes: 1
Reputation: 7082
Could you try this:
public string origData { get; set; }
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex == 1)
origData = dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue.ToString().Trim(); //Get the original data
}
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
if (e.ColumnIndex == 1)
{
if (origData != dataGridView1[e.ColumnIndex, e.RowIndex].EditedFormattedValue.ToString().Trim()) //If not equal to original data will trigger
{
//Do stuff
}
}
}
}
Upvotes: 1