DataGridView EditMode强制单元格编辑仅设CurrentCell和Focus无法生效问题
解决方案
核心问题原因
你遇到的两个问题有明确的触发原因:
- 焦点无法落到单元格:模态窗口关闭后父窗体还未完成激活,且你原有代码的执行顺序错误,先调用
Focus再设置CurrentCell,导致焦点定位失效 - 赋值后不触发
CellValidating:直接给单元格Value属性赋值不会触发该事件,CellValidating仅在用户编辑后尝试离开单元格、或主动调用EndEdit提交编辑时才会触发
调整后的实现代码
' 赋值单元格内容 myGrid.Rows(myGrid.Rows.Count - 1).Cells("EID").Value = 1 ' 用BeginInvoke将操作抛到UI消息队列尾部,等父窗体完全激活后执行 Me.BeginInvoke(Sub() ' 1. 先指定当前要激活的单元格 myGrid.CurrentCell = myGrid("EID", myGrid.Rows.Count - 1) ' 2. 再让DataGridView获取焦点 myGrid.Focus() ' 3. 进入编辑模式,参数True默认全选内容 myGrid.BeginEdit(True) ' 可选:如果需要赋值后立刻触发已有校验逻辑,手动调用校验 Dim validateArgs = New DataGridViewCellValidatingEventArgs( myGrid.CurrentCell.ColumnIndex, myGrid.CurrentCell.RowIndex ) validateArgs.FormattedValue = myGrid.CurrentCell.Value myGrid.OnCellValidating(validateArgs) ' 校验不通过时保持编辑状态 If validateArgs.Cancel Then myGrid.BeginEdit(True) End If ' 兼容处理:如果BeginEdit没有自动全选,手动操作编辑控件 If TypeOf myGrid.EditingControl Is TextBox Then CType(myGrid.EditingControl, TextBox).SelectAll() End If End Sub)
关键调整说明
- 操作顺序调整:必须先设置
CurrentCell再调用Focus,否则焦点无法落到目标单元格 BeginInvoke的作用:模态窗口调用Close后,父窗体还在处理激活相关的系统消息,此时直接操作焦点会失败,放入消息队列尾部等待父窗体激活完成后再执行,就能正确定位焦点- 校验触发逻辑:如果不需要赋值立刻校验,只要后续用户修改值时触发校验,可以删掉手动调用
OnCellValidating的代码,进入编辑状态后用户修改值离开时会自动触发原有校验逻辑
内容的提问来源于stack exchange,提问作者Jortx
相关产品推荐
相关产品推荐

