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

C#子窗体向主窗体回传文本数据问题:空引用异常求助

解决System.NullReferenceException问题的方案

咱们先直接戳破问题根源:你搞反了事件的订阅逻辑,而且在子窗体的按钮点击事件里错误地把sender转换成Form1——但实际用户点击按钮时,sender是按钮控件本身,不是主窗体实例,这才导致了空引用异常。

错误原因拆解

看你主窗体这段代码:

CharAdded += uif.btnAdd_Click;
//Call Event
if (CharAdded != null) {
    CharAdded(this, new EventArgs());
}

你把主窗体的CharAdded事件和子窗体的btnAdd_Click方法绑定了,触发事件时是主窗体调用这个方法,此时sender确实是主窗体实例。但当用户真正点击子窗体的Add按钮时,这个方法的sender是Button控件,你用Form1 mainForm = sender as Form1;转换,自然得到null,调用mainForm.GetData()就会抛出空引用异常。

正确的实现方式

我们应该让子窗体在用户输入完成后主动触发事件传递数据,主窗体订阅这个事件来接收并处理数据,步骤如下:

1. 简化Character类(可选,让代码更简洁)

public class Character {
    // 用自动属性代替手动实现的私有字段
    public string Name { get; set; }

    public override string ToString() {
        return Name;
    }
}

2. 修改UserInputForm子窗体代码

在子窗体里定义一个事件,当用户点击添加按钮时触发,把输入的名字传出去:

public partial class UserInputForm : Form {
    // 定义事件,用于传递输入的角色名称
    public event Action<string> OnCharacterAdded;

    public UserInputForm() {
        InitializeComponent();
    }

    private void btnAdd_Click(object sender, EventArgs e) {
        // 先校验输入不为空
        if (string.IsNullOrWhiteSpace(txtName.Text)) {
            MessageBox.Show("请输入角色名称!");
            return;
        }

        // 触发事件,传递输入的名字(空安全调用)
        OnCharacterAdded?.Invoke(txtName.Text);
        // 可选:添加完成后关闭子窗体
        this.Close();
    }
}

3. 修改主窗体Form1的代码

在打开子窗体时,订阅子窗体的事件,接收数据并添加到列表:

public partial class Form1 : Form {
    public List<Character> charList = new List<Character>();

    public Form1() {
        InitializeComponent();
    }

    private void GetData(string name) {
        Character c = new Character();
        c.Name = name;
        charList.Add(c);
        // 这里可以更新UI,比如把列表绑定到ListBox:
        // listBoxCharacters.DataSource = null;
        // listBoxCharacters.DataSource = charList;
    }

    private void btnCreateChar_Click(object sender, EventArgs e) {
        UserInputForm uif = new UserInputForm();
        // 订阅子窗体的事件,接收数据并处理
        uif.OnCharacterAdded += (characterName) => {
            GetData(characterName);
        };
        // 用ShowDialog模态打开子窗体,或者用Show非模态,看你的需求
        uif.ShowDialog();
    }
}

为什么这样能解决问题?

  • 事件流向更合理:子窗体负责收集用户输入,在用户确认后触发事件传递数据;主窗体负责订阅事件,接收数据并处理。
  • 不再依赖sender转换获取主窗体实例,彻底避免了空引用的风险。
  • 代码逻辑更清晰,符合WinForms中父子窗体交互的常规做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:56