如何在C#中将子表单的子数据传递给父表单?

我是c#的新手。 我在Windows窗体的项目中有以下内容:

Form1带按钮和DataGridView。

Form2带按钮。

Form3带按钮和3个文本框。

截图

如截屏In form1所示,我点击buttonOpenForm2 form2弹出。 然后在form2中我点击buttonOpenForm3 form3弹出,其中有3个文本框和按钮。 现在这三种forms是开放的。

我在textBox1,textBox2和textBox3中输入值,当单击buttonAddRow(从form3)时,我希望将这些值插入到Form1中的DataGRidView中。

我的问题是:如何从form3(子窗体的子窗口)向Form1(父)中的DataGridView添加一行而不关闭form2和form3? 我的意思是我想传递数据,而form2和form3仍然是打开的。

请帮我。 谢谢

Form1中:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonOpenForm2 _Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.Show(); } } 

窗体2:

 public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void buttonOpenForm3 _Click(object sender, EventArgs e) { Form3 frm3 = new Form3(); frm3.Show(); } } 

Form3:

  public partial class Form3 : Form { public Form3() { InitializeComponent(); } private void buttonAddRow _Click(object sender, EventArgs e) { //What to write here to insert the 3 textboxes values into DataGridView? } } 

您不能指望获得可以粘贴的完整代码。 我很快在记事本中写了这篇文章,让你了解事件在这种情况下如何发挥最佳作用。 我假设Form1直接打开Form3。 下面的解决方案显示了如何使用事件

您的家庭工作是通过在两者之间添加另一个表单Form2来使其工作。 您可以通过位于中间的Form2传播相同的事件来实现。

Form3.cs

 public partial class Form3 : Form { public event EventHandler RecordAdded public Form3() { InitializeComponent(); } private void buttonAddRow _Click(object sender, EventArgs e) { OnRecordAdded(); } private void OnRecordAdded() { var handler = RecordAdded; if(RecordAdded != null) { RecordAdded.Invoke(this, new AddRecordEventArgs(txtQty.Text, txtDesc.Text, txtPrice.Text)) } } } 

AddRecordEventArgs.cs

 public class AddRecordEventArgs : EventArgs { public AddRecordEventArgs(string qty, string desc, string price) { Quantity = qty; Description = desc; Price = price; } public int Quantity { get; private set; } public string Description { get; private set; } public decimal Price { get; private set; } } 

Form1.cs的

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void buttonOpenForm3_Click(object sender, EventArgs e) { Form3 frm3 = new Form3(); frm3.RecordAdded += Form3_RecordAdded; frm3.Show(); } private void Form3_RecordAdded(object sender, AddRecordEventArgs e) { // Access e.Quantity, e.Description and e.Price // and add new row in grid using these values. } } 

1解决方案

您可以使用模式通过构造函数(Show方法之前的特殊setter)进一步发送数据,并在窗口被public getter关闭后将它们恢复。

 public partial class Form2 : Form { Data Data1 {get; set;} //Instead of Data you can pass Form1 class as parametr. //But this might lead to unreadable code, and using too mutch methods and fields that could be private, public public Form2(Data data) { InitializeComponent(); Data1 = data; } private void buttonOpenForm3 _Click(object sender, EventArgs e) { //Repeat pattern Form3 frm3 = new Form3(Data1); frm3.Show(); } } 

您可以选择不必调用第3窗口构造函数。 只需创建第三个窗口的实例,将其存储在第一个窗体中,然后通过调用传递给数据的第一个实例来显示它。 但这可能是更大规模的不良做法。

2解决方案

您可以使用单例模式。 在第一个表单的构造函数中创建第一个表单的实例,并以第三个forms使用它。 但是你需要确保在内存中不会有一个并且总是有一个这个对象的实例。

您可以将所有者传递给方法Show()以获取新表单。 然后,您可以从Owner属性获取所有者表单。

 private void buttonOpenForm2 _Click(object sender, EventArgs e) { Form2 frm2 = new Form2(); frm2.Show(this); } 

所以你可以获得Form1:

 (Form1)frm2.Owner 

并调用Form1类的公共方法并传递新数据。