4

I am trying to call a method on my parent form from a child form, which in turn calls a method in my custom user control. I am able to make the call if I do this...

In child form:

private void btnSaveNode_Click(object sender, EventArgs e)
{
    frmMain frm = new frmMain();
    frm.getNodeData(txtPartName.Text);
    this.Hide();
}

In parent form:

public void getNodeData(string partNbr)
{
    string strPartNbr = partNbr;
    buildNode(strPartNbr);
}

public void buildNode(string partNbr)
{
    drewsTreeView tv = new drewsTreeView();
    tv.addNode(partNbr);
}

And finally, the method in the user control

public void addNode(string strPartNbr)
{
    btnNode.Location = new Point(13, 13);
    btnNode.Width = 200;
    btnNode.Height = 40;
    //btnNode.Text = strPartNbr;
    btnNode.Text = "Testing";
    this.Controls.Add(btnNode);
    btnNode.Click += btnNode_Click;
}

So my problem is, the button does not get built in the addNode() method. If I call the method in the onLoad event of the main form, it builds just fine. I ran in debug mode, and I can see the method is getting called and the correct parameters are getting passed.

So why will it build the button when called from the parent, but not when called from the child?

3
  • Because you are creating a new form, not using the existing form. You need to pass a reference to the existing main form to the child form so that it can call methods on that instance, not create a new instance which you hide right away anyway (which is unnecessary because you never call .Show). Commented Jul 6, 2015 at 3:36
  • How are you displaying the child form? With Show(), or ShowDialog()? Commented Jul 6, 2015 at 3:39
  • Displaying with Show(). Commented Jul 6, 2015 at 5:17

2 Answers 2

4

One way to do this is to pass in your instance of frmMain to the Form.Show() method:

// ... in frmMain, displaying the "child" form:
frmChild child = new frmChild(); // <-- whatever your child type is
child.Show(this); // passing in a reference to frmMain via "this"

Now over in your child form code, you can cast the Form.Owner property back to your frmMain type and do something with it:

private void btnSaveNode_Click(object sender, EventArgs e)
{
    frmMain frm = (frmMain)this.Owner;
    frm.getNodeData(txtPartName.Text);
    // ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Your solution worked perfectly. My issue was that I was trying to add a control to a new instance of the main form rather than the existing form. Once I passed in, "this", when opening form 2, it worked great. Thank you for your help.
1

In general, if you instantiate a form in a method call and you don't do something with it like save it to an instance variable or Show() it then you're making a mistake. That form is never seen by the user and just gets garbage collected after your method exits.

Also, you are modifying the same button in basically the same way and adding it to the same form multiple times. Don't do this. Learn about reference semantics.

If you want your child form to be able to cause something to happen in the parent form, you could have the parent give a reference to itself to the child. It would be better to have the parent provide a delegate to the child that the child can invoke as needed.

1 Comment

Thanks for your input. I will research your advice. I understand that I am probably not seeing the architecture correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.