You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法聚焦DataGridView指定列colAdjust及事件执行顺序问题求助

解决方案

问题1:调整事件执行顺序,确保CellValueChanged先执行

CellValidating事件触发于单元格值即将提交到数据源之前,此时CellValueChanged还未执行(值尚未真正更新到DataTable)。要让依赖CellValueChanged的业务逻辑先完成,需将验证逻辑迁移到CellEndEdit事件——该事件在单元格编辑结束、值已提交到数据源后触发,此时CellValueChanged已执行完毕,数据源也完成更新。

问题2:让colAdjust列获取焦点

在CellValidating事件中直接设置CurrentCell不会生效,因为控件正处于编辑状态,状态变更会被事件流程覆盖。在CellEndEdit事件中设置焦点更稳妥,此时编辑状态已结束,控件状态稳定;也可通过异步调用延迟执行焦点设置。

修改后的代码示例

' 替换原CellValidating事件,改用CellEndEdit处理验证和焦点设置
Private Sub dgvKnockOff_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKnockOff.CellEndEdit
    If bFirstLoad Then Return

    Dim currentRow As DataGridViewRow = dgvKnockOff.Rows(e.RowIndex)
    Dim currentRowID = currentRow.Cells(colIDDgvKnockOff.Name).Value
    If currentRowID Is Nothing Then Return

    Dim drs As DataRow() = dtPayment.Select($"id = '{currentRowID}'")
    If drs.Length = 0 Then Return

    Dim dr As DataRow = drs(0)
    If CBool(dr("chk")) Then
        Dim balance = Convert.ToDecimal(dr("balance"))
        Dim adjustAmt = Convert.ToDecimal(dr("adjust_amount"))

        ' 根据balance正负调整adjust值
        If balance < 0D Then
            adjustAmt = Math.Abs(balance)
            dr("adjust_amount") = adjustAmt ' 将调整后的值写回DataTable
        End If
    End If

    ' 仅提交当前行的更改,避免影响其他未确认的修改
    dr.AcceptChanges()

    ' 设置焦点到colAdjust列
    dgvKnockOff.CurrentCell = currentRow.Cells(colAdjust.Name)
End Sub

' 保留你的CellValueChanged事件(负责复选框点击后初始化adjust列)
Private Sub dgvKnockOff_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles dgvKnockOff.CellValueChanged
    ' 原有逻辑:复选框点击后将balance值传入adjust列
    If e.ColumnIndex = colChkDgvKnockOff.Index Then
        Dim currentRow = dgvKnockOff.Rows(e.RowIndex)
        Dim currentRowID = currentRow.Cells(colIDDgvKnockOff.Name).Value
        If currentRowID Is Nothing Then Return

        Dim drs As DataRow() = dtPayment.Select($"id = '{currentRowID}'")
        If drs.Length > 0 Then
            Dim dr = drs(0)
            dr("adjust_amount") = dr("balance")
        End If
    End If
End Sub

额外优化点

  • 原代码中dtPayment.AcceptChanges()会提交整个DataTable的所有更改,改为dr.AcceptChanges()仅提交当前行的更改,避免误操作未确认的修改。
  • 使用字符串插值$"id = '{currentRowID}'"替代字符串拼接,代码更简洁易读。
  • 增加currentRowID Is Nothing的空值判断,避免空引用异常。

内容的提问来源于stack exchange,提问作者agaesh kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:42:47