简体   繁体   English

如何在C#中将数据从子窗体的子窗体传递到父窗体?

[英]How do I pass data from child of child form to parent form in C#?

I am new to c#. 我是C#的新手。 I have the following in my project in windows forms: 我的Windows窗体项目中包含以下内容:

Form1 with button and DataGridView. 带按钮和DataGridView的Form1。

Form2 with button. 带按钮的Form2。

Form3 with button and 3 textBoxes. 带按钮和3个文本框的Form3。

截图

As shown in the screenshot In form1, I click buttonOpenForm2 form2 pops up. 如屏幕截图所示,在form1中,我单击buttonOpenForm2,将弹出form2。 Then in form2 I click buttonOpenForm3 form3 pops up which has 3 text boxes and button. 然后在form2中,我单击buttonOpenForm3,弹出带有3个文本框和按钮的form3。 Now the 3 forms are open. 现在,这3个表单已打开。

I enter values in textBox1, textBox2 and textBox3 and when click buttonAddRow ( from form3) I want these values to be inserted into the DataGRidView in Form1. 我在textBox1,textBox2和textBox3中输入值,当单击buttonAddRow(来自form3)时,我希望将这些值插入到Form1中的DataGRidView中。

My question is: How can I add a row into DataGridView in Form1 ( parent) from form3 (child of child form) WITHOUT closing form2 and form3? 我的问题是:如何在不关闭form2和form3的情况下从form3(子窗体的子窗体)向Form1(父窗体)的DataGridView中添加一行? I mean I want to pass the data while form2 and form3 are still open. 我的意思是我想在form2和form3仍处于打开状态时传递数据。

Please help me. 请帮我。 Thank you 谢谢

Form1: Form1中:

public partial class Form1 : Form
{


    public Form1()
    {
        InitializeComponent();

    }

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

}

Form2: 窗体2:

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void buttonOpenForm3 _Click(object sender, EventArgs e)
    {
        Form3 frm3 = new Form3();
        frm3.Show();
    }
}

Form3: 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?

    }
}

You cannot expect to get complete code that's ready to be pasted. 您不能期望获得准备好粘贴的完整代码。 I quickly wrote this in notepad to give you idea about how events work best in such cases. 我很快在记事本中写了这个,以使您了解在这种情况下事件如何最好地工作。 I assumed Form1 directly opens Form3. 我假设Form1直接打开Form3。 Solution below shows how to use events. 下面的解决方案显示了如何使用事件。

You home work is to make it work by adding another form Form2 in between. 您要做的工作是通过在两者之间添加另一个Form2使其工作。 You can do so by propagating same event via Form2 which sits in middle. 您可以通过中间的Form2传播同一事件来实现。

Form3.cs Form3.cs

public partial class Form3 : Form
{
    public event EventHandler<AddRecordEventArgs> 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 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 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 Solution 1解决方案

You can use pattern with sending data further by constructor (special setter before Show method) and getting them back after window is closed by public getter. 您可以使用模式,通过构造函数(Show方法之前的特殊setter)进一步发送数据,并在公共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();
    }    
}

Optionally you dont have to call 3rd window constuctor. (可选)您不必调用第三窗口构造函数。 Just create Instance of third window store it in first form and just Show it by calling first instance you passed with data. 只需创建第三个窗口的Instance以第一种形式存储它,然后通过调用您与数据一起传递的第一个实例来显示它即可。 But this might be bad practice in larger scale. 但这在较大范围内可能是不好的做法。

2 Solution 2解决方案

You can use singleton pattern. 您可以使用单例模式。 Create Instance of an first form inside constructor of first form and use it in third form. 在第一种形式的构造函数中创建第一种形式的实例,并在第三种形式中使用它。 But you would need to ensure that there will be no more then one and always one instance of this object in memory. 但是,您需要确保内存中此对象的实例不超过一个,并且始终只有一个。

You can pass owner to method Show() for new forms. 您可以将所有者传递给方法Show()以获取新表单。 Then you can get owner form from Owner property. 然后,您可以从Owner属性获取所有者表单。

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

So you can get Form1: 因此,您可以获得Form1:

(Form1)frm2.Owner

and call public method of Form1 class and pass there your new data. 并调用Form1类的public方法并将新数据传递到那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM