Click here to Skip to main content
15,881,139 members
Articles / Programming Languages / C#
Tip/Trick

Transferring information between two forms, Part 2: Child to Parent

Rate me:
Please Sign up or sign in to vote.
3.82/5 (23 votes)
3 Apr 2013CPOL4 min read 71.7K   1.7K   20   13
Questions here quite often ask "how do I send data from one form to another?" and I must have answered this a dozen times. So, a series of three tips to cover the process.

Introduction

It's a common problem. How do you transfer data between two forms in a Windows Forms application? And it's really easy to do. But...there are too many people out there that will tell you to just "make the control public" and set the value. Unfortunately that's a very bad idea - and the proper way is not a lot more complex.

This could have been an article, but I wanted to keep it focused (because this is information for a beginner  and felt that a tip for each of the common transfers might work better.  

So, a set of three Tips: 

Part1: Parent to Child Transferring information between two forms, Part 1: Parent to Child[^]

  • Covers transferring data from a Parent form to it's Child form when the Parent want's to.
Part2: Child to Parent Transferring information between two forms, Part 2: Child to Parent[^
  • Covers transferring data from the Child to the Parent when the Child wants to. 
Part3: Child to Child Transferring information between two forms, Part 3: Child to Child[^
  • Covers transferring data from a Child to another Child when the first Child wants to. 

Background  

If "making the control public" works, why is is it private by default? Why not do that and move on? It's easy to do and it works!

The answer is that when you do that, you are exposing the internals of your form to the whole world - and that is not a good idea, because:

  1. It's against the principles of OOPs 
  2. It locks the design of the two forms together - you can't change one form without considering it's effects on the other.  Suppose you have a TextBox in a child, and  you make it public. You now can't change it to any other control (or do anything with it at all, pretty much) because it might break the form that is using it. This makes your life a lot harder when you have a small change to make, because suddenly it's a small change to the child, and a massive set of changes to the parent.
  3. When you make a control public, you don't just expose the field you want: myTextBox.Text. Oh, no - you expose them all. Font, SizeLocationBackColor, then lot. And there is nothing stopping any external class from changing them, while your form is running. Nasty...
So, instead, do it properly - it takes very little time and really does save you work later on!  

Using the code 

There are three basic ways that data needs to be transferred: this tip covers when the Child wants to change data on its Parent. This is a more complex operation than going from the Parent to the Child, but the way that is often suggested is to create a Parent Form reference in the Child and set that when the Child is created. It can then access the parent and do what it has to.

The problem with that approach is that it's even worse than making your control public: it ties the two forms together much, much more tightly - now the Parent has to know about the Child, and the Child has to know about the Parent. Which means that you can't reuse the Child form from a different type of parent, or without a parent altogether. And that's bad - because if you create a form for changing the details of your Widget class, you will probably want to use it from the "NewWidget" form, and your "EditWidget" form. If your Widget Details form is hard coded to expect a "NewWidget" form, then it won't work with an "EditWidget" and you end up duplicating work with all the opportunities for error that that provides.

Instead, use the Event method to let the Child tell the Parent there is data to work with. 

The Event method  

This is really simple: you create a property in the Child to supply the data, and an Event to say the data is available. The Parent handles the Event, fetches the data and does with it what it wants.

Child Form property

C#
/// <summary>
/// Data to transfer into / out of form
/// </summary>
public string Data
    {
    get { return tbData.Text; }
    set { tbData.Text = value; }
    }

Child Form Event

C#
/// <summary>
/// Event to indicate new data is available
/// </summary>
public event EventHandler DataAvailable;
/// <summary>
/// Called to signal to subscribers that new data is available
/// </summary>
/// <param name="e"></param>
protected virtual void OnDataAvailable(EventArgs e)
    {
    EventHandler eh = DataAvailable;
    if (eh != null)
        {
        eh(this, e);
        }
    }

Then all the Child form has to do is signal the Event to indicate the data is ready. In this case, we will do it when the user presses a button.

C#
/// <summary>
/// Tell the parent the data is ready.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void butTransfer_Click(object sender, EventArgs e)
    {
    OnDataAvailable(null);
    }

The parent form just has to add the handler when it creates the form instance:

C#
// Add a child form
frmChild child = new frmChild();
child.DataAvailable += new EventHandler(child_DataAvailable);
child.Data = "Hello child 1 from the Parent!";
child.Show();

And the Parent handles the Event to fetch the data, and in this case displays it in a TextBox:

C#
/// <summary>
/// The child has data available - get it.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void child_DataAvailable(object sender, EventArgs e)
    {
    frmChild child = sender as frmChild;
    if (child != null)
        {
        tbData.Text = child.Data;
        }
    }

In this case, we don't even need to save the Child form instance, because the Event mechanism passes it to the Parent when the event occurs.

The information could easily be transferred with the Event by creating a custom EventArgs, but in most cases that isn't necessary. 

History

  • 2013-02-18: First version 
  • 2013-02-19: Added links to other tips in series  
  • 2013-04-03: Corrected spelling error in title: "Transfering" should have been "Transferring"  
  • 2013-04-03 Corrected the same spelling error in the links to companion tips...  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO
Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

Comments and Discussions

 
GeneralMy vote of 5 Pin
Bice9017-Sep-20 6:41
Bice9017-Sep-20 6:41 
QuestionFantastic and easy Pin
Fernando Maresca22-Oct-19 12:37
Fernando Maresca22-Oct-19 12:37 
GeneralPassing Data between forms Pin
Member 1184305820-Jul-15 3:09
Member 1184305820-Jul-15 3:09 
Questionthx Pin
ivana123417-Jan-15 0:37
ivana123417-Jan-15 0:37 
thx for your nice example Smile | :)
GeneralMy vote of 5 Pin
Raul Iloc25-Mar-14 22:18
Raul Iloc25-Mar-14 22:18 
QuestionApproved! Pin
Sandeep Mewara18-Feb-13 5:16
mveSandeep Mewara18-Feb-13 5:16 
AnswerRe: Approved! Pin
OriginalGriff18-Feb-13 5:23
mveOriginalGriff18-Feb-13 5:23 
GeneralRe: Approved! Pin
Sandeep Mewara18-Feb-13 5:32
mveSandeep Mewara18-Feb-13 5:32 
GeneralRe: Approved! Pin
OriginalGriff18-Feb-13 5:34
mveOriginalGriff18-Feb-13 5:34 
GeneralRe: Approved! Pin
Sandeep Mewara18-Feb-13 5:45
mveSandeep Mewara18-Feb-13 5:45 
GeneralRe: Approved! Pin
OriginalGriff18-Feb-13 5:48
mveOriginalGriff18-Feb-13 5:48 
GeneralRe: Approved! Pin
Sandeep Mewara18-Feb-13 6:02
mveSandeep Mewara18-Feb-13 6:02 
GeneralRe: Approved! Pin
Thomas Daniels18-Feb-13 6:33
mentorThomas Daniels18-Feb-13 6:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.