【问题标题】:Repopulate DataGridView on CellEndEdit在 CellEndEdit 上重新填充 DataGridView
【发布时间】:2014-03-27 01:56:05
【问题描述】:

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

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

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

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

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

BeginInvoke(new MethodInvoker(PopulateAccounts));

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

同样,这发生在点击离开单元格并进入另一个单元格时。否则,即按 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;
                }
            }
        }
    }

【问题讨论】:

  • 您可以在帖子中添加 PopulateAccounts 代码吗?
  • 完成。 dgvShed.Rows.Clear() 方法抛出错误。

标签: c# winforms datagridview


【解决方案1】:

在单元格中输入值后,如果用户按键盘上的 Enter 或单击表单上的另一个控件,一切都会正常运行

上述操作不会改变CurrentCell,并且网格重新填充工作正常。

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

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

在上述情况下,我的猜测是DataGridView 不知何故弄乱了单元格的选择。您可以简单地使用DataGridView.ClearSelection() 方法清除PopulateAccounts 末尾的选择。

【讨论】:

  • 抱歉,我忘了说明我曾尝试在 PopulateAccounts() 方法之后使用 ClearSelection(),它根本没有任何效果。由于 CellEndEdit 更新了数据库,我意识到我不一定需要在此事件处理程序中重新填充 DataGridView,因为单元格已经包含与数据库完全相同的值(它只是技术上未绑定到数据库)。因此,除非有人知道如何解决一般知识的单元格选择问题,否则这对我来说不再是问题。
【解决方案2】:

我一直在努力解决几乎完全相同的问题,只是想出了一个适合我的具体情况的解决方案。我将所有代码从 CellEndEdit 事件移到 CellValueChanged 事件(在前者之前触发),现在结束单元格编辑的两个选项:输入笔划和单击另一个单元格,效果很好。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 2019-11-02
    相关资源
    最近更新 更多