在CellEndEdit上重新填充DataGridView

时间:2014-03-27 01:56:06

标签: c# winforms datagridview

我正在尝试在用户完成编辑单元格后更新数据库中的值。由于DataBinding涉及此特定数据集的一些复杂性,DataGridView是手动填充的(并且是动态的)。

CellEndEdit的事件处理程序中,我调用了我的方法将值更新回数据库,它按计划运行。当我尝试重新填充DataGridView时出现问题。作为参考,此方法称为PopulateAccounts()

在单元格中输入值后,如果用户在键盘上按 Enter 或单击表单上的其他控件,一切都会正常工作。但是,单击同一DataGridView中的另一个单元格会导致以下错误:

  

操作无效,因为它导致对SetCurrentCellAddressCore函数的可重入调用。

PopulateAccounts()方法包含引发错误的DataGridView.Rows.Clear()。我在一些相关的SO问题中研究了这个错误,它似乎与线程有关,我对此一无所知。一个建议的解决方法是调用我的PopulateAccounts()方法:

BeginInvoke(new MethodInvoker(PopulateAccounts));

这样可行,但它会导致DataGridView选择所编辑的单元格之前的所有单元格(参见下面的屏幕截图)

faultyDGV

同样,当单击单元格并进入另一单元格时,会发生 。否则,即按 Enter 或点击另一个控件,它只需选择第一个单元格。

以下是PopulateAccounts()的代码供参考:

    // Populates the DataGridView's account records.
    private void PopulateAccounts()
    {
        dgvShed.Rows.Clear();

        using (PassShedEntities context = new PassShedEntities(conString))
        {
            foreach (Account acct in context.Account.Where(a => a.Category_id == (int)lstCategories.SelectedValue))
            {
                dgvShed.Rows.Add();

                foreach (DataGridViewColumn col in dgvShed.Columns)
                {
                    Credential cred = (from c in context.Credential
                                       join f in context.Field on c.Field_id equals f.Id
                                       join a in context.Account on c.Account_id equals a.Id
                                       where c.Account_id == acct.Id
                                       where f.Label == col.Name
                                       select c).SingleOrDefault();

                    dgvShed.Rows[dgvShed.Rows.Count - 1].Cells[col.Name].Tag = cred.Id;
                    dgvShed.Rows[dgvShed.Rows.Count - 1].Cells[col.Name].Value = cred.Value;
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

在单元格中输入值后,如果用户在键盘上按Enter键或单击表单上的其他控件

,则一切正常

以上操作不会更改CurrentCell,网格重新填充也可以正常工作。

但是,单击同一DataGridView中的另一个单元格会导致以下错误:

当您点击另一个单元格时,数据网格视图的CurrentCell正在更改,网格在内部调用SetCurrentCellAddressCore进行单元格更改。此调用在内部引发CellEndEdit事件,该事件再次触发SetCurrentCellAddressCore,此循环继续,导致无限循环。 DataGridView检测到此循环并抛出异常,导致您提到的错误。

在上面的例子中,我的猜测是DataGridView以某种方式搞砸了细胞的选择。您只需使用PopulateAccounts方法清除DataGridView.ClearSelection()末尾的选择。

答案 1 :(得分:0)

我一直在努力解决完全相同的问题,并提出了一个适用于我的细节的解决方案。我将所有代码从CellEndEdit事件移动到CellValueChanged事件(它在前者之前触发),现在结束单元格编辑的两个选项:输入笔划并单击关闭到另一个单元格,工作得很好。

我不确定使用这些事件的正确方法是什么,但这似乎有效!