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

如何将类对象从子窗体传递到MainForm?配方管理器开发问题

问题根源分析

你遇到的空引用异常,核心原因是在AddIngredients窗体中新建了一个全新的Form1实例,而非引用当前正在运行的主窗体。你给这个新实例的currentRecipe赋值,但和用户实际操作的主窗体完全无关,导致原主窗体的currentRecipe始终为null。

看你AddIngredients里的错误代码:

Form1 mainForm = new Form1(); // 这里创建的是新窗体,不是用户正在操作的主窗体
mainForm.passCurrentRecipe(currentRecipe);
解决方案

下面提供两种常用修复方式,选一种即可:

方式一:通过构造函数传递主窗体引用

1. 修改AddIngredients窗体代码

添加私有字段保存主窗体和Recipe对象的引用,修改构造函数接收主窗体实例:

private Form1 _mainForm;
private Recipe _currentRecipe;

// 修改构造函数
public AddIngredients(Form1 mainForm, Recipe currentRecipe)
{
    InitializeComponent();
    _mainForm = mainForm;
    _currentRecipe = currentRecipe;
}

private void validate_ingredients_btn_Click(object sender, EventArgs e)
{
    // 赋值配料
    for(int i =0; i < currentIngredients.Length; i++)
    {
        _currentRecipe.Ingredients[i] = currentIngredients[i];
    }

    // 用保存的主窗体引用赋值
    _mainForm.passCurrentRecipe(_currentRecipe);
    Close();
}

2. 修改MainForm(Form1)代码

打开AddIngredients时传递主窗体实例this,并直接给类级别的currentRecipe赋值:

private void addingredients_btn_Click(object sender, EventArgs e)
{
    // 直接给类的currentRecipe字段赋值
    this.currentRecipe = new Recipe
    {
        Name = addrecipe_textbox.Text,
        Category = addcategory_combobox.Text,
        Description = addrecipe_textbox.Text // 注意:这里原代码写的是addrecipe_textbox,应对应描述文本框,比如add_description_textbox.Text,根据实际控件名调整
    };

    // 传递主窗体和Recipe对象
    AddIngredients ingredientsManager = new AddIngredients(this, this.currentRecipe);
    ingredientsManager.ShowDialog();
}

方式二:用对话框返回值+属性传递(更优雅,低耦合)

这种方式无需直接引用主窗体,符合WinForms对话框设计模式:

1. 修改AddIngredients窗体代码

添加属性返回更新后的Recipe,设置DialogResult标记操作完成:

private Recipe _originalRecipe;
// 暴露属性供主窗体获取更新后的Recipe
public Recipe UpdatedRecipe { get; private set; }

public AddIngredients(Recipe originalRecipe)
{
    InitializeComponent();
    _originalRecipe = originalRecipe;
}

private void validate_ingredients_btn_Click(object sender, EventArgs e)
{
    // 赋值配料
    for(int i =0; i < currentIngredients.Length; i++)
    {
        _originalRecipe.Ingredients[i] = currentIngredients[i];
    }

    UpdatedRecipe = _originalRecipe;
    this.DialogResult = DialogResult.OK; // 标记操作成功
    Close();
}

2. 修改MainForm(Form1)代码

在ShowDialog后,根据DialogResult判断是否获取更新后的Recipe:

private void addingredients_btn_Click(object sender, EventArgs e)
{
    var tempRecipe = new Recipe
    {
        Name = addrecipe_textbox.Text,
        Category = addcategory_combobox.Text,
        Description = addrecipe_textbox.Text // 注意控件名是否正确
    };

    AddIngredients ingredientsManager = new AddIngredients(tempRecipe);
    // 对话框关闭后,判断用户是否确认操作
    if (ingredientsManager.ShowDialog() == DialogResult.OK)
    {
        this.currentRecipe = ingredientsManager.UpdatedRecipe;
    }
}
验证修复

完成修改后,点击「添加配方」按钮时,this.currentRecipe已被正确赋值,不会再抛出空引用异常,可正常调用recipeMngr.addRecipe(currentRecipe)添加配方。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:45:34