How to determine if a DataGridView contains uncommitted changes when binding to SqlDataAdapter

I have a form that contains a DataGridView, BindingSource, DataTable and SqlDataAdapter. I fill the grid and data bindings as follows:

private BindingSource bindingSource = new BindingSource(); private DataTable table = new DataTable(); private SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * FROM table ORDER BY id ASC;", ClassSql.SqlConn()); private void LoadData() { table.Clear(); dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = bindingSource; SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); table.Locale = System.Globalization.CultureInfo.InvariantCulture; dataAdapter.Fill(table); bindingSource.DataSource = table; } 

The user can then make changes to the data and commit these changes or discard them by clicking the save or cancel button, respectively.

 private void btnSave_Click(object sender, EventArgs e) { // save everything to the displays table dataAdapter.Update(table); } private void btnCancel_Click(object sender, EventArgs e) { // alert user if unsaved changes, otherwise close form } 

I would like to add a dialog if the cancel button is pressed, which warns the user about unsaved changes, if there are unsaved changes.

Question:

How can I determine if the user changed the data in the DataGridView, but did not transfer it to the database? Is there an easy way to compare the current DataGridView data with the last request received? (Note that there would be no other threads or users changing data in SQL at the same time.)

+4
source share
4 answers

To detect the changes in the DataGridView, I ended up using two events: CellValueChanged and CurrentCellDirtyStateChanged (the latter because of check type columns).

When one of these events occurs, I set a boolean value (UnsavedChanges) to indicate that changes exist. When the form is closed or the cancel button is pressed (now renamed to "Revert"), the logical value is checked and a dialog box is displayed if set to true. If you click the save button, boolean will be set to false and the data will be saved.

Although it is not as simple as checking a single data binding or datagrid property, it works as desired.

+2
source

It might be a dumb question, but why doesn't it work?

for vb

 Dim changes As DataTable = table.GetChanges() If changes.Rows.Count > 0 Then MessageBox.Show("You have unsaved edits!") End If 

for c #

 DataTable changes = table.GetChanges(); if (changes.Rows.Count > 0) MessageBox.Show("You have unsaved edits!"); 

If your datatable is linked through a source of bindings to your datagridview, then your recently modified but uncommitted changes are posted in your datatable. Datasets and date files have the GetChanges() method, which can do the hard work of the exam and return to you exactly what was edited, and nothing else works accordingly.

+2
source

Well, I play with the trick, I hope this helps all of you, I track the changes using the bindingsource CurrentItemChanged method. Here I used the tag property for datagridview to mark the changes, you can use the variable:

  private void cONTRACTERBindingSource_CurrentItemChanged(object sender, EventArgs e) { if (cONTRACTERDataGridView.Tag==null) { DataRow ThisDataRow = ((DataRowView)((BindingSource)sender).Current).Row; if (ThisDataRow.RowState == DataRowState.Modified) cONTRACTERDataGridView.Tag = "1"; } } 

Remember that this trigger could be fired many times, so both if statements control the launch once, really. Finally, you can use this code in the exit button handler, as in my code code here:

 private void btExit_Click(object sender, EventArgs e) { if (cONTRACTERDataGridView.Tag.Equals("1")) { if (MessageBox.Show("Do you want to save the changes..!?", "Save Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) cONTRACTERBindingNavigatorSaveItem_Click(null, null); } this.Close(); } 

Discard changes, reset flag. Hope this works for you, too.

Hi

0
source

when working with a small table with a data set, not wanting to deal with the event of a cell change and cancel editing, you can use several improved options:

  private bool isDGVRowDirty(DataGridView dgv, int idxrow) { if (idxrow < 0) return false; DataGridViewRow dgvRow = dgv.Rows[idxrow]; DataRowView rowview = (DataRowView)dgvRow.DataBoundItem; DataRow row = rowview.Row; if (row.RowState == DataRowState.Unchanged) return false; if (row.RowState != DataRowState.Added || row.RowState == DataRowState.Modified) { return true; } for (int idxCol = 0; idxCol < dgv.Columns.Count - 1; idxCol++) if (dgv[idxCol, idxrow].FormattedValue.ToString() != dgv[idxCol, idxrow].Value.ToString()) return true; return false; } 
0
source

Source: https://habr.com/ru/post/1309445/


All Articles