VB.NET Datagridview底行按Enter键无法触发CellValidating事件如何解决
解决方案
问题根因
DataGridView最后一行单元格按下Enter时,由于没有后续行可供焦点跳转,当前单元格不会触发失去焦点逻辑,因此CellValidating事件不会被触发。
实现方案
方案1:使用PreviewKeyDown事件(无需修改窗体基类)
直接给DataGridView绑定PreviewKeyDown事件,检测到最后一行按下Enter时主动结束编辑触发校验:
Private Sub DGV_Risk_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles DGV_Risk.PreviewKeyDown ' 仅处理最后一行按下Enter的场景 If e.KeyCode = Keys.Enter AndAlso DGV_Risk.CurrentRow IsNot Nothing AndAlso DGV_Risk.CurrentRow.Index = DGV_Risk.Rows.Count - 1 Then ' 主动结束当前单元格编辑,会自动触发CellValidating事件 DGV_Risk.EndEdit() ' 若需要按下Enter后保持在当前单元格,取消注释下一行 ' e.IsInputKey = True End If End Sub
方案2:重写窗体ProcessCmdKey方法(兼容性更佳)
不会被其他控件按键拦截逻辑影响,适配性更高:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean If keyData = Keys.Enter AndAlso DGV_Risk.Focused AndAlso DGV_Risk.CurrentRow IsNot Nothing AndAlso DGV_Risk.CurrentRow.Index = DGV_Risk.Rows.Count - 1 Then DGV_Risk.EndEdit() End If Return MyBase.ProcessCmdKey(msg, keyData) End Function
原有代码优化建议
原CellValidating事件中直接修改单元格Value可能触发重复校验,建议调整为如下逻辑:
Private Sub DGV_Risk_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles DGV_Risk.CellValidating If e.ColumnIndex <> 1 Then Exit Sub Dim Entry As String = e.FormattedValue?.ToString() If String.IsNullOrWhiteSpace(Entry) Then Return If Not User.Items.Contains(Entry) Then User.Items.Add(Entry) End If e.Cancel = False End Sub Private Sub DGV_Risk_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DGV_Risk.CellValidated If e.ColumnIndex <> 1 Then Exit Sub DGV_Risk.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = DGV_Risk.Rows(e.RowIndex).Cells(e.ColumnIndex).FormattedValue End Sub
内容的提问来源于stack exchange,提问作者pball
相关产品推荐
相关产品推荐

