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

时间:2015-11-26 16:09:27

标签: c#

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

Form1,带按钮和DataGridView。

Form2 with button。

Form3,带按钮和3个文本框。

screenshot

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

我在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?

    }
}

3 个答案:

答案 0 :(得分:2)

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

您的家庭工作是通过在其间添加另一种形式Form2来使其工作。您可以通过位于中间的Form2传播相同的事件来完成此操作。

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

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 :(得分:1)

1解决方案

您可以使用模式通过构造函数(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();
    }    
}

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

2解决方案

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

答案 2 :(得分:1)

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

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

所以你可以得到Form1:

(Form1)frm2.Owner

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