C#窗体切换时数据丢失求助:弹窗数据无法保留至主窗体
问题描述
在C# WinForms中实现弹窗交互:点击MainForm的buttonBegin按钮弹出Manual_Input窗体,在弹窗输入信息后点击buttonEnter,期望将数据传回主窗体并保存到临时变量,点击主窗体buttonNext查看数据。但调试发现数据虽被赋值,点击next后数据丢失。
相关代码
MainForm(主窗体)
namespace estController { public partial class MainForm : Form { string Tempcustomer = ""; string TempManager = ""; string TempManagerId = ""; string TempName = ""; string TempProjectId = ""; string TempSharePointID = ""; string Tempstatus = ""; private void buttonBegin_Click(object sender, EventArgs e) { if(ManualEnterNumber.Checked) { buttonBegin.Enabled = false; Manual_Input F2 = new Manual_Input(); F2.Show(); } } private void buttonNext_Click(object sender, EventArgs e) { MessageBox.Show("test" + TempName); } internal void receiveData(string boxCustomer, string boxManager, string boxManagerId, string boxName, string boxProjectId, string boxSharePointId, string boxStatus) { Tempcustomer = boxCustomer; TempManager = boxManager; TempManagerId = boxManagerId; TempName = boxName; TempProjectId = boxProjectId; TempSharePointID = boxSharePointId; Tempstatus = boxStatus; } } }
Manual_Input(弹窗窗体)
namespace estController { public partial class Manual_Input : Form { private void buttonEnter_Click(object sender, EventArgs e) { MainForm Form = new MainForm(); Form.receiveData(boxCustomer.Text, boxManager.Text, boxManagerId.Text, boxName.Text, boxProjectId.Text, boxSharePointId.Text, boxStatus.Text); this.Close(); } } }
注:代码非复制粘贴,可能存在错误,仅保留关键部分。
问题根源
弹窗的buttonEnter_Click方法里新建了全新的MainForm实例,你调用的receiveData是给这个新实例的变量赋值,而不是给原来打开弹窗的那个主窗体实例赋值。新实例在方法执行完后就被销毁,原主窗体的临时变量根本没被修改,所以点击buttonNext看不到数据。
解决方案
提供两种常用的修正方式:
方式一:通过构造函数传递主窗体引用
- 修改Manual_Input的构造函数,接收MainForm实例:
namespace estController { public partial class Manual_Input : Form { private MainForm _mainForm; // 新增带参数的构造函数 public Manual_Input(MainForm mainForm) { InitializeComponent(); _mainForm = mainForm; } private void buttonEnter_Click(object sender, EventArgs e) { // 使用传递过来的主窗体实例调用receiveData _mainForm.receiveData(boxCustomer.Text, boxManager.Text, boxManagerId.Text, boxName.Text, boxProjectId.Text, boxSharePointId.Text, boxStatus.Text); this.Close(); } } }
- 修改MainForm中打开弹窗的代码,传入自身实例:
private void buttonBegin_Click(object sender, EventArgs e) { if(ManualEnterNumber.Checked) { buttonBegin.Enabled = false; // 传入当前主窗体实例 Manual_Input F2 = new Manual_Input(this); F2.Show(); } }
方式二:使用ShowDialog+公开属性(更解耦)
这种方式不需要直接依赖主窗体实例,通过弹窗的公开属性返回数据:
- 在Manual_Input中定义公开属性存储输入的数据:
namespace estController { public partial class Manual_Input : Form { // 定义公开属性 public string Customer { get; private set; } public string Manager { get; private set; } public string ManagerId { get; private set; } public string Name { get; private set; } public string ProjectId { get; private set; } public string SharePointId { get; private set; } public string Status { get; private set; } private void buttonEnter_Click(object sender, EventArgs e) { // 给属性赋值 Customer = boxCustomer.Text; Manager = boxManager.Text; ManagerId = boxManagerId.Text; Name = boxName.Text; ProjectId = boxProjectId.Text; SharePointId = boxSharePointId.Text; Status = boxStatus.Text; // 设置DialogResult表示确认输入 this.DialogResult = DialogResult.OK; this.Close(); } } }
- 修改MainForm中打开弹窗的代码,通过ShowDialog获取返回值并更新变量:
private void buttonBegin_Click(object sender, EventArgs e) { if(ManualEnterNumber.Checked) { buttonBegin.Enabled = false; Manual_Input F2 = new Manual_Input(); // 使用ShowDialog等待弹窗关闭 if(F2.ShowDialog() == DialogResult.OK) { // 从弹窗的属性获取数据,赋值给主窗体变量 Tempcustomer = F2.Customer; TempManager = F2.Manager; TempManagerId = F2.ManagerId; TempName = F2.Name; TempProjectId = F2.ProjectId; TempSharePointID = F2.SharePointId; Tempstatus = F2.Status; } } }
注意:如果使用ShowDialog,弹窗会以模态方式打开,用户必须关闭弹窗才能操作主窗体,适合需要强制输入的场景;如果需要非模态,还是推荐方式一。
内容的提问来源于stack exchange,提问作者UnstoppablEagle
相关产品推荐
相关产品推荐

