[英]DataGridView editable cell input overwritten when another cell is updated
我有一個通過BindingSource
綁定到DataTable
的DataGridView
,並且我的網格具有用戶可在其中輸入值的可編輯列,以及一些以編程方式實時更新的只讀列(例如股票行情自動收錄器)。 對於以編程方式更新的列,我正在更新DataTable
的值,然后由於數據綁定而更新了DataGridView中的值。 我遇到的問題是,當用戶編輯一個單元格時,如果以編程方式更新另一個單元格,則用戶在第一個單元格中輸入的文本將被覆蓋(在編輯之前重置為該單元格的值)。
在我看來,這似乎並不罕見,但我似乎無法使其正常工作。 任何人都知道我可能做錯了什么,或者可以將我引向一個顯示如何正確執行此操作的示例?
發生這種情況的原因是,當DataTable
的基礎值更改時,會觸發DataGridView.DataBindingComplete
事件-重置綁定。
我的第一個建議是捕獲該事件,然后僅檢查CurrentCell
的EditedFormattedValue
是否不同於Value
如果是,則設置Value
。 這一直有效-直到我檢查了第一行-才完全忽略了我的邏輯。
我能找到一直有效的唯一解決方案是更改編程實時更新的發生方式。 如果可能的話,不更新DataTable
列,而是更新DataGridView
列。 這些更改將永久保留在源中,但綁定不會重置-因此,您當前的編輯單元不會丟失任何更改。
foreach (DataRow row in this.table.Rows) { row[1] = someNewValue; }
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
row.Cells[1].Value = someNewValue;
}
最后我解決了這個問題,因此我將在這里添加解決方案,以防對他人有所幫助。
我處理了DataGridView
的CellBeginEdit
, CellEndEdit
和CurrentCellDirtyStateChanged
事件,並添加了以下代碼:
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);
}
我還發現, DataGridView
的Esc鍵功能不僅還原了對當前處於編輯模式的單元格的更改,還還原了直接在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
保存編輯之前單元格的值(在DataGridView
的CellBeginEdit
事件處理程序中設置)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.