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

WinForms多窗体调用Change()触发NullReferenceException问题排查

WinForms多窗体修改数据空引用异常解决方法

问题核心原因

子窗体点击Change按钮时,创建了全新的MainForm实例,这个新实例的dataGridView1既没有加载数据库数据,也没有选中行,导致dataGridView1.CurrentCell为null,触发空引用异常。同时主窗体的Change()方法里还新建了Full_Inf_Form实例,根本拿不到当前打开的子窗体中修改后的数据。

具体解决方案

1. 子窗体持有主窗体的真实引用

修改子窗体代码,添加接收主窗体实例的构造函数,保存主窗体引用:

// 子窗体类内添加私有字段保存主窗体引用
private MainForm _mainForm;

// 重写子窗体构造函数,接收主窗体实例
public Full_Inf_Form(MainForm mainForm)
{
    InitializeComponent();
    _mainForm = mainForm;
}

// 修改Change按钮点击事件
private void buttonChange2_Click(object sender, EventArgs e)
{
    // 调用已有主窗体的Change方法,传递当前子窗体实例
    _mainForm.Change(this);
}

2. 主窗体打开子窗体时传递自身实例

修改主窗体打开子窗体的代码,传入当前主窗体实例:

// 确保selectedRow是主窗体的类级别字段
private int selectedRow = -1;

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    selectedRow = e.RowIndex;

    if (e.RowIndex >= 0)
    {
        // 传入当前主窗体实例创建子窗体
        Full_Inf_Form fullInfForm = new Full_Inf_Form(this);

        DataGridViewRow row = dataGridView1.Rows[selectedRow];

        fullInfForm.textBoxID_Inf.Text = row.Cells[0].Value.ToString();
        fullInfForm.textBoxStNa_Inf.Text = row.Cells[1].Value.ToString();
        fullInfForm.textBoxLaNa_Inf.Text = row.Cells[2].Value.ToString();
        fullInfForm.textBoxStPa_Inf.Text = row.Cells[3].Value.ToString();
        fullInfForm.textBoxNumb_Inf.Text = row.Cells[4].Value.ToString();
        fullInfForm.textBoxEmail_Inf.Text = row.Cells[5].Value.ToString();
        fullInfForm.textBoxGrup_Inf.Text = row.Cells[6].Value.ToString();
        fullInfForm.textBoxSpec_Inf.Text = row.Cells[7].Value.ToString();
        fullInfForm.textBoxDataVst_Inf.Text = row.Cells[8].Value.ToString();
        fullInfForm.textBoxStSt_Inf.Text = row.Cells[9].Value.ToString();
        fullInfForm.textBoxBalMat_Inf.Text = row.Cells[10].Value.ToString();
        fullInfForm.textBoxBalUkr_Inf.Text = row.Cells[11].Value.ToString();
        fullInfForm.textBoxBalEng_Inf.Text = row.Cells[12].Value.ToString();
        fullInfForm.Show();
    }
}

3. 修改主窗体Change方法,接收子窗体数据

调整主窗体Change()方法,直接从传入的子窗体实例获取修改后的数据,并用已保存的选中行索引操作:

// 修改Change方法,接收子窗体实例
public void Change(Full_Inf_Form currentSubForm)
{
    // 校验选中行索引有效性
    if (selectedRow < 0 || selectedRow >= dataGridView1.Rows.Count)
        return;

    // 从传入的子窗体获取修改后的数据
    var id = currentSubForm.textBoxID_Inf.Text;
    var name = currentSubForm.textBoxStNa_Inf.Text;
    var lastname = currentSubForm.textBoxLaNa_Inf.Text;
    var patr = currentSubForm.textBoxStPa_Inf.Text;
    var numb = currentSubForm.textBoxNumb_Inf.Text;
    var email = currentSubForm.textBoxEmail_Inf.Text;
    var grup = currentSubForm.textBoxGrup_Inf.Text;
    var spec = currentSubForm.textBoxSpec_Inf.Text;
    var data = currentSubForm.textBoxDataVst_Inf.Text;
    var sypend = currentSubForm.textBoxStSt_Inf.Text;
    var mat = currentSubForm.textBoxBalMat_Inf.Text;
    var ukr = currentSubForm.textBoxBalUkr_Inf.Text;
    var eng = currentSubForm.textBoxBalEng_Inf.Text;

    var targetRow = dataGridView1.Rows[selectedRow];
    // 安全校验单元格值
    if (!string.IsNullOrEmpty(targetRow.Cells[0].Value?.ToString()))
    {
        targetRow.SetValues(id, name, lastname, patr, numb, email, grup, spec, data, sypend, mat, ukr, eng);
        targetRow.Cells[13].Value = RowState.Modified;
    }
}

关键说明

  • 核心逻辑是共享实例而非新建实例:子窗体操作的是已经加载数据的主窗体,不是空的新实例;
  • 用类级别字段selectedRow保存选中行索引,比依赖CurrentCell更可靠,避免主窗体焦点丢失导致CurrentCell为空的情况;
  • 通过传递子窗体实例直接获取修改后的数据,无需重新创建子窗体。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:52:48