更新另一个单元格时,DataGridView可编辑单元格输入被覆盖

时间:2016-02-08 05:07:45

标签: c# winforms data-binding datagridview datagrid

我有一个DataGridView通过BindingSource绑定到DataTable,我的网格包含用户输入值的可编辑列,以及一些以编程方式显示的只读列实时更新(想像股票代码)。对于以编程方式更新的列,我正在更新DataTable中的值,然后由于数据绑定而更新DataGridView中的值。 我遇到的问题是,当用户正在编辑一个单元格时,如果另一个单元格以编程方式更新,则用户在第一个单元格中输入的文本将被覆盖(在单元格之前重置为单元格的值)编)。

这对我来说似乎不是一个不寻常的情况,但我似乎无法让它正常工作。任何人都知道我可能做错了什么,或者可以指出一个示例,说明如何正确地做到这一点?

2 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为当DataTable中的基础值发生更改时,DataGridView.DataBindingComplete事件会被触发 - 重置绑定。

My first suggestion是您捕获此事件并检查EditedFormattedValue的{​​{1}}是否与CurrentCell不同 - 如果是,则设置{{1 }}。这工作 - 直到我检查了第一行 - 这完全忽略了我的逻辑。

我唯一能找到的解决方案就是改变程序化实时更新的发生方式。如果可能,只需更新Value列,而不是更新Value列。这些更改将持续到源,但绑定不会重置 - 因此您当前的编辑单元格不会丢失任何更改。

<击>

<击>
DataTable

<击>

DataGridView

答案 1 :(得分:0)

最后我把它解决了,所以我会在这里添加我的解决方案,以防它对其他人有帮助。

我处理了CellBeginEdit的{​​{1}},CellEndEditCurrentCellDirtyStateChanged事件,并添加了以下代码:

DataGridView

我还发现private void Grid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { ((DataRowView)((DataGridView)sender).Rows[e.RowIndex].DataBoundItem).BeginEdit(); } private void Grid_CellEndEdit(object sender, DataGridViewCellEventArgs e) { // need this check for when the program is closed while a cell is in edit mode // otherwise an IndexOutOfRangeException occurs if (((BindingSource)((DataGridView)sender).DataSource).List.Count > e.RowIndex) ((DataRowView)((DataGridView)sender).Rows[e.RowIndex].DataBoundItem).EndEdit(); } private void Grid_CurrentCellDirtyStateChanged(object sender, EventArgs e) { // commit changes to the table as soon as they are entered so they don't // get overwritten when the DataTable is updated if (Grid.IsCurrentCellDirty) Grid.CommitEdit(DataGridViewDataErrorContexts.Commit); } 的Esc键功能不仅恢复了当前处于编辑模式的单元格的更改,还恢复了直接在DataGridView中设置值的更改(实时编程更新),所以我改编了DataTable的Esc键功能,如下所示:

DataGridView

其中protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (CurrentCell != null && CurrentCell.IsInEditMode) { if (keyData == (Keys.Escape)) { CurrentCell.Value = valueBeforeEdit; EditingControl.Text = valueBeforeEdit.ToString(); EndEdit(); return true; } } return base.ProcessCmdKey(ref msg, keyData); } 在编辑之前保存单元格的值(在valueBeforeEdit的{​​{1}}事件处理程序中设置)。