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

DataGridView RowValidating事件取消操作报错问题求助

DataGridView RowValidating取消操作报错的解决方法

错误原因

你推测的没错:窗体加载时设置DataSource的过程中,DataGridView会自动触发RowValidating事件,此时控件内部的单元格值提交状态还不稳定,直接设置e.Cancel = true就会抛出无法提交或取消单元格值更改的异常。

可行解决方案

1. 用加载标记跳过初始化阶段的验证

这是你当前思路的优化写法,逻辑更清晰:

private bool _isFormLoaded = false;

private void form_Load(Object sender, EventArgs e)
{
    dtTest = new DataTable();
    dtTest.Columns.Add("ID", typeof(int));
    dtTest.Columns.Add("Name", typeof(string));

    dtTest.Rows.Add(1, "John");
    dtTest.Rows.Add(2, "Amy");
    dtTest.Rows.Add(3, "Tony");

    dataGridView1.DataSource = dtTest;
    // 加载完成后标记,后续验证才生效
    _isFormLoaded = true;
}

private void dataGridView1_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
    // 初始化阶段直接跳过验证
    if (!_isFormLoaded) return;

    if (isEmpty(e.RowIndex))
    {
        e.Cancel = true;
        return;
    }
    // 其他验证逻辑
}

2. 改用CellValidating事件(适合单元格级验证)

如果你的验证是针对单个单元格的,用CellValidating更精准,而且初始化时的触发逻辑更稳定,不容易出异常:

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    // 跳过表头行
    if (e.RowIndex < 0) return;
    
    string cellValue = e.FormattedValue.ToString().Trim();
    if (string.IsNullOrEmpty(cellValue))
    {
        e.Cancel = true;
        // 可以给行设置错误提示
        dataGridView1.Rows[e.RowIndex].ErrorText = "当前单元格不能为空";
    }
    else
    {
        dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty;
    }
}

3. 延迟绑定DataSource到窗体Shown事件

把数据源绑定移到Shown事件,此时窗体已经完全加载完成,DataGridView状态稳定,初始化时不会触发异常:

private void form_Load(Object sender, EventArgs e)
{
    // 只初始化DataTable,不绑定数据源
    dtTest = new DataTable();
    dtTest.Columns.Add("ID", typeof(int));
    dtTest.Columns.Add("Name", typeof(string));

    dtTest.Rows.Add(1, "John");
    dtTest.Rows.Add(2, "Amy");
    dtTest.Rows.Add(3, "Tony");
}

private void form_Shown(object sender, EventArgs e)
{
    // 窗体完全显示后再绑定数据源
    dataGridView1.DataSource = dtTest;
}

private void dataGridView1_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
    if (isEmpty(e.RowIndex))
    {
        e.Cancel = true;
        return;
    }
    // 其他验证逻辑
}

选择建议

  • 如果是整行级别的验证,方法1或3都可以,方法3更彻底避免初始化阶段的事件干扰;
  • 如果是单个单元格的验证,优先用方法2,逻辑更贴合场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:09:50