naouf
naouf

Reputation: 637

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

I am new to c#. I have the following in my project in windows forms:

Form1 with button and DataGridView.

Form2 with button.

Form3 with button and 3 textBoxes.

screenshot

As shown in the screenshot In form1, I click buttonOpenForm2 form2 pops up. Then in form2 I click buttonOpenForm3 form3 pops up which has 3 text boxes and button. Now the 3 forms are open.

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.

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? I mean I want to pass the data while form2 and form3 are still open.

Please help me. Thank you

Form1:

public partial class Form1 : Form
{


    public Form1()
    {
        InitializeComponent();

    }

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

}

Form2:

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?

    }
}

Upvotes: 4

Views: 4651

Answers (3)

iceberg
iceberg

Reputation: 596

You can pass owner to method Show() for new forms. Then you can get owner form from Owner property.

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

So you can get Form1:

(Form1)frm2.Owner

and call public method of Form1 class and pass there your new data.

Upvotes: 2

Tomasz Juszczak
Tomasz Juszczak

Reputation: 2340

1 Solution

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.

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. But this might be bad practice in larger scale.

2 Solution

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.

Upvotes: 1

Nikhil Vartak
Nikhil Vartak

Reputation: 5127

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. Solution below shows how to use events.

You home work is to make it work by adding another form Form2 in between. You can do so by propagating same event via Form2 which sits in middle.

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.
    }
}

Upvotes: 4

Related Questions