代码之家  ›  专栏  ›  技术社区  ›  JYelton Melchior Blausand

如何确定绑定到sqldataadapter时,DataGridView是否包含未提交的更改

  •  4
  • JYelton Melchior Blausand  · 技术社区  · 14 年前

    我有一个包含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 回复  |  直到 6 年前
        1
  •  2
  •   JYelton Melchior Blausand    14 年前

    为了检测DataGridView中的更改,我使用了两个事件, CellValueChanged CurrentCellDirtyStateChanged (后者是由于复选框类型的列所致)。

    当这些事件发生时,我设置了一个布尔值(unsavedChanges),以指示存在更改。关闭窗体或单击“取消”按钮(现在重命名为“还原”)时,将选中布尔值,如果设置为true,则显示对话框。如果单击“保存”按钮,则布尔值设置为“假”,并保存数据。

    虽然不像检查数据绑定或数据报的一个属性那么简单,但它可以根据需要工作。

        2
  •  2
  •   guntbert Spoike    6 年前

    这可能是个愚蠢的问题,但为什么这个问题不起作用呢?

    对于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!");
    

    如果数据表是通过绑定源绑定到DataGridView的,那么您最近修改但未提交的编辑将挂起在数据表中。数据集和数据表具有 GetChanges() 方法可以做艰苦的考试工作,并返回给你准确的编辑,没有更多的东西,并相应地操作。

        3
  •  0
  •   qbaloch    11 年前

    嗯,我在玩一个小把戏,希望它能帮助你们所有人,我正在使用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";
                }
            }
    

    记住,这个触发器可以多次触发,因此两个if语句都可以真正地控制一次运行。最后,您可以在退出按钮处理程序上使用此代码,正如我的示例代码所示:

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

    在取消更改时,重置标志。希望它也对你有用。

    当做

        4
  •  0
  •   gg89    8 年前

    在处理带有数据集的小表时,如果不想处理单元格更改事件和取消编辑,可以使用以下改进的变体:

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