簡體   English   中英

更新另一個單元格時,DataGridView可編輯單元格輸入將被覆蓋

[英]DataGridView editable cell input overwritten when another cell is updated

我有一個通過BindingSource綁定到DataTableDataGridView ,並且我的網格具有用戶可在其中輸入值的可編輯列,以及一些以編程方式實時更新的只讀列(例如股票行情自動收錄器)。 對於以編程方式更新的列,我正在更新DataTable的值,然后由於數據綁定而更新了DataGridView中的值。 我遇到的問題是,當用戶編輯一個單元格時,如果以編程方式更新另一個單元格,則用戶在第一個單元格中輸入的文本將被覆蓋(在編輯之前重置為該單元格的值)。

在我看來,這似乎並不罕見,但我似乎無法使其正常工作。 任何人都知道我可能做錯了什么,或者可以將我引向一個顯示如何正確執行此操作的示例?

發生這種情況的原因是,當DataTable的基礎值更改時,會觸發DataGridView.DataBindingComplete事件-重置綁定。

我的第一個建議是捕獲該事件,然后僅檢查CurrentCellEditedFormattedValue是否不同於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;
}

最后我解決了這個問題,因此我將在這里添加解決方案,以防對他人有所幫助。

我處理了DataGridViewCellBeginEditCellEndEditCurrentCellDirtyStateChanged事件,並添加了以下代碼:

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保存編輯之前單元格的值(在DataGridViewCellBeginEdit事件處理程序中設置)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM