如何将类对象从子窗体传递到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
相关产品推荐
相关产品推荐

