简体   繁体   中英

DataGridView Row update event

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?

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
                }
            }
        }
    }

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;
   }
}

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();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM