C#如何从其他窗体刷新Textbox控件 跨窗体操作出现对象引用报错如何解决
报错原因
你遇到的报错本质是混淆了窗体类和窗体实例的概念:Cartel_Form是你定义的窗体类,相当于创建窗口的模板,而Textbox_Revenu是类的非静态成员,必须通过已经创建好的、正在运行的窗口实例对象访问,不能直接用类名访问,这就是报错提示要求你提供对象引用的原因。
可行解决方法
下面提供三种常用的解决思路,可根据你的项目场景选择:
方案1:全局存储目标窗体实例
适合项目规模小、逻辑简单的场景:
- 首先在你已经定义的
Variables静态类中新增字段,存储Cartel_Form的运行实例:
public static Cartel_Form RunningCartelForm;
- 在你创建并打开
Cartel_Form的位置,把实例赋值给这个字段:
Cartel_Form cartelWindow = new Cartel_Form(); Variables.RunningCartelForm = cartelWindow; cartelWindow.Show();
- 之后修改控件时直接访问这个实例即可:
private void Button2_Click(object sender, EventArgs e) { Variables.revenu += Variables.LAIR * 30; // 访问前建议判空,避免窗口已关闭时报空引用错误 if(Variables.RunningCartelForm != null) { Variables.RunningCartelForm.Textbox_Revenu.Text = Variables.revenu.ToString(); } }
方案2:事件委托实现(更规范的低耦合方案)
适合需要保持代码可维护性、不想公开控件的场景,不需要把控件修饰符设为public也能实现:
- 在你当前点击按钮的窗体类中定义委托和更新事件:
public delegate void RevenuUpdateDelegate(int newRevenuValue); public event RevenuUpdateDelegate RevenuUpdated;
- 按钮点击时触发事件:
private void Button2_Click(object sender, EventArgs e) { Variables.revenu += Variables.LAIR * 30; // 如果有订阅者就触发事件,传递新的revenu值 RevenuUpdated?.Invoke(Variables.revenu); }
- 在
Cartel_Form中打开当前窗体的位置,订阅这个事件,收到通知后自行更新自己的控件:
// 假设你当前点击按钮的窗体类名为EditForm EditForm editWindow = new EditForm(); editWindow.RevenuUpdated += (newVal) => { // 这里是Cartel_Form内部,可直接访问自己的控件,不需要公开修饰符 this.Textbox_Revenu.Text = newVal.ToString(); }; editWindow.Show();
方案3:遍历运行中的窗体查找实例
如果不方便修改Variables类或者窗口打开逻辑,可以直接从应用进程的打开窗体中查找目标实例:
using System.Linq; // 需要引入Linq命名空间 private void Button2_Click(object sender, EventArgs e) { Variables.revenu += Variables.LAIR * 30; // 查找当前打开的所有Cartel_Form实例 Cartel_Form targetWindow = Application.OpenForms.OfType<Cartel_Form>().FirstOrDefault(); if(targetWindow != null) { targetWindow.Textbox_Revenu.Text = Variables.revenu.ToString(); } }
内容的提问来源于stack exchange,提问作者Kaiger Chainer
相关产品推荐
相关产品推荐

