VB.NET中DataGridView在RowEnter事件执行.Rows.Clear()报错求助
DataGridView在RowEnter事件中执行Rows.Clear()报错的解决方法
问题场景
使用VB.NET 2022+SQLite开发数据库应用,DataGridView加载源表两列数据,在RowEnter事件中检查记录:当源表布尔列BlankFrame为True时弹出提示框,用户选NO则更新记录并调用RecycleForm()重置窗体(清空DGV后重新加载)。此时执行dgvRecords.Rows.Clear()会触发Operation cannot be performed in this event handler错误,但通过按钮事件触发相同的RecycleForm()则正常。
核心原因
RowEnter事件是DataGridView正在处理行选中状态的内部事件,此时控件处于状态变更的临界流程中,直接修改行集合(如Clear())会干扰控件的内部状态机,导致异常。
解决方案
将重置DGV的操作异步延迟到当前事件处理完成后执行,使用Control.BeginInvoke()把操作放到UI线程的消息队列末尾。
方法一:异步调用RecycleForm
修改DataGrid_SelectRow中调用RecycleForm()的代码:
If FLBG_CustomMsgBox(strDGVCell01 & " " & noticeBlankFrame, __ModuleLongName, "QYN") = vbNo Then FLBG_TableRecordUpdate(appDataSource, tableArchive, "[InLibrary]=True", strFilterString) ' 用BeginInvoke异步执行重置,避免在RowEnter事件中直接修改DGV Me.BeginInvoke(Sub() RecycleForm()) Exit Sub End If
方法二:单独异步执行Rows.Clear()
如果不想整体异步调用RecycleForm(),可以只修改ResetVariables()中的报错行:
' 替换原来的dgvRecords.Rows.Clear() dgvRecords.BeginInvoke(Sub() dgvRecords.Rows.Clear())
说明
BeginInvoke()会将传入的委托放到UI线程的消息队列中,等当前的RowEnter事件处理完所有逻辑、控件状态稳定后,再执行DGV的清空操作,从根源上避免了状态冲突。
内容的提问来源于stack exchange,提问作者Graf Eberstein
相关产品推荐
相关产品推荐

