开发者

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

I have a form which contains a DataGridView, a BindingSource, a DataTable, and a SqlDataAdapter. I populate 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 those changes or discard them by开发者_StackOverflow社区 clicking either a 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 cancel is clicked that warns the user of unsaved changes, if unsaved changes exist.

Question:

How can I determine if the user has modified data in the DataGridView but not committed it to the database? Is there an easy way to compare the current DataGridView data to the last-retrieved query? (Note that there would not be any other threads or users altering data in SQL at the same time.)


In order to detect changes in the DataGridView, I wound up using two events, the CellValueChanged and CurrentCellDirtyStateChanged (the latter due to checkbox type columns).

When either of those events occurs, I set a boolean (UnsavedChanges) to indicate changes exist. When the form is closed or if the cancel button (now renamed to "Revert") is clicked, the boolean is checked and the dialog shown if set to true. If the save button is clicked, the boolean is set to false and the data saved.

While not as simple as checking one property of the databinding or datagrid, it works as desired.


This may be a dumb question but why wouldn't this 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 bound through a bindingsource to your datagridview then your recently modified but uncommitted edits are hanging out in your datatable. Datasets and datatables have a GetChanges() method that can do the hard examination work and return to you exactly what was edited and nothing more and operate accordingly.


Well I am Playing around a trick hope it will help you all, I am tracking the changes using bindingsource's CurrentItemChanged method. Here I have used tag property of datagridview to flag the changes, you might use a 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, this trigger could be fired many times, therefore both if statements control the run once, truly. Finally you might this code on exit button handler, as in my case code is 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();
        }

On Cancel Changes, reset the flag. Hope It Works For You, Too.

Regards


when dealing with small table with dataset while don't want to deal with cell change event and cancel edit, one could use some improved variant of:

    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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜