Как определить, содержит ли DataGridView незафиксированные изменения при привязке к SqlDataAdapter - PullRequest
5 голосов
/ 11 мая 2010

У меня есть форма, которая содержит DataGridView, BindingSource, DataTable и SqlDataAdapter. Я заполняю сетку и привязки данных следующим образом:

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

Затем пользователь может вносить изменения в данные и фиксировать эти изменения или отменять их, нажимая соответственно кнопку сохранения или отмены.

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
}

Я хотел бы добавить диалоговое окно, если нажата кнопка отмены, которое предупреждает пользователя о несохраненных изменениях, если существуют несохраненные изменения.

Вопрос:

Как определить, изменил ли пользователь данные в DataGridView, но не зафиксировал их в базе данных? Есть ли простой способ сравнить текущие данные DataGridView с последним полученным запросом? (Обратите внимание, что не было бы других потоков или пользователей, изменяющих данные в SQL в то же время.)

Ответы [ 4 ]

2 голосов
/ 28 июля 2011

Это может быть глупый вопрос, но почему бы не работать?

для VB

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

для C #

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

Если ваша таблица данных связана через источник привязки с вашей сеткой данных, то ваши недавно измененные, но незафиксированные изменения висят в вашей таблице данных. Наборы данных и таблицы данных имеют метод GetChanges(), который может выполнить сложную экзаменационную работу и вернуть вам именно то, что было отредактировано и ничего более, и действовать соответствующим образом.

2 голосов
/ 12 мая 2010

Чтобы обнаружить изменения в DataGridView, я использовал два события: CellValueChanged и CurrentCellDirtyStateChanged (последнее из-за столбцов типа флажка).

Когда происходит любое из этих событий, я устанавливаю логическое значение (UnsavedChanges), чтобы указать, что изменения существуют. Когда форма закрыта или если нажата кнопка отмены (теперь переименованная в «Вернуть»), проверяется логическое значение, и отображается диалоговое окно, если установлено значение true. Если нажата кнопка «Сохранить», логическое значение устанавливается в «ложь», а данные сохраняются.

Хотя это не так просто, как проверка одного свойства привязки данных или сетки данных, оно работает как нужно.

0 голосов
/ 31 мая 2016

при работе с небольшой таблицей с набором данных, когда вы не хотите иметь дело с событием смены ячейки и отменой редактирования, можно использовать улучшенный вариант:

    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 голосов
/ 05 апреля 2013

Что ж, я обдумываю трюк, надеюсь, он вам всем поможет, я отслеживаю изменения, используя метод CurrentItemChanged от bindingsource. Здесь я использовал свойство тега datagridview, чтобы пометить изменения, вы можете использовать переменную:

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

Помните, что этот триггер может быть запущен много раз, поэтому оба оператора действительно управляют выполнением один раз. Наконец, вы можете добавить этот код в обработчик кнопки выхода, как в моем случае код здесь:

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

При отмене изменений сбросьте флаг. Надеюсь, у вас это тоже получится.

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...