我正在尝试在用户完成编辑单元格后更新数据库中的值。由于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;
}
}
}
}
答案 0 :(得分:1)
在单元格中输入值后,如果用户在键盘上按Enter键或单击表单上的其他控件
,则一切正常以上操作不会更改CurrentCell
,网格重新填充也可以正常工作。
但是,单击同一DataGridView中的另一个单元格会导致以下错误:
当您点击另一个单元格时,数据网格视图的CurrentCell
正在更改,网格在内部调用SetCurrentCellAddressCore
进行单元格更改。此调用在内部引发CellEndEdit
事件,该事件再次触发SetCurrentCellAddressCore
,此循环继续,导致无限循环。 DataGridView
检测到此循环并抛出异常,导致您提到的错误。
在上面的例子中,我的猜测是DataGridView
以某种方式搞砸了细胞的选择。您只需使用PopulateAccounts
方法清除DataGridView.ClearSelection()
末尾的选择。
答案 1 :(得分:0)
我一直在努力解决完全相同的问题,并提出了一个适用于我的细节的解决方案。我将所有代码从CellEndEdit事件移动到CellValueChanged事件(它在前者之前触发),现在结束单元格编辑的两个选项:输入笔划并单击关闭到另一个单元格,工作得很好。
我不确定使用这些事件的正确方法是什么,但这似乎有效!