Page 1 of 1

How to Get Values From Form1 to Form2 (or any other forms).

#1 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 21 December 2010 - 01:33 PM

*
POPULAR

This question is asked practically every day in the C# Forum: "how do I get a value from Form1 to Form2?" or the other way around. There is a shocking amount of bad advice out there on the internet about how to go about doing this. This tutorial is intended to show you more "correct" ways of passing data between forms.

Note that this info is not limited only to forms. It can be used on any kind of class. Forms are the ones most frequently asked about, so the tutorial is written from that perspective, but otherwise, the info in the Modeless section works for any kind of classes that need values to be passed around.

The scope of this tutorial is limited to passing data between forms. We will look at both properties and custom events, but in a brief overview. There are already some excellent tutorials that cover some of these topics in more detail, should you want more information:
Quick and easy custom events
Bulding an application - Part 1
Building an application - Part 2

Let's start with a new Windows Forms project (though note, these methods can also be used for WPF forms as well). I'm creating three forms: DefaultForm, FirstNameForm, and LastNameForm. DefaultForm is "Form1", the Form that is opened when the application starts.

There are two types of child form: modal and modeless (non-modal). There are different techniques for getting information from both, since they behave differently.

Modeless child windows do not require an immediate response, and do not block you from focusing the parent form again. You are allowed to freely switch back and forth between them. An example of a modeless dialog would be the "Find" (ctrl+F) dialog in Visual Studio.

Modal dialogs, on the other hand, block you from switching back to the parent window. They require a response before continuing. An example of a modal dialog is a MessageBox.

Depending on which type of form you choose to use, you will need to get the data from it differently.

Modeless

First, we'll visit modeless forms. A form is treated as modeless when it is opened by the .Show method. Execution does not stop on that line; the code after it continues to execute even though the child form is now shown and focused.

We'll use FirstNameForm as the modeless dialog.

Since execution does not stop, we need a way to know when the value we want is updated. Custom events are the answer. The reason we like to use events rather than just passing properties around is that we don't want to tightly couple our forms. DefaultForm doesn't need to know anything more about FirstNameForm than it should. This way, it doesn't have to know anything about it other than that it has one event. It doesn't need to know names of properties, and it doesn't have to guess about when the properties are updated.

Another benefit is reusability. You may want several forms to update themselves when a child window does. This way, each form can subscribe to the event and handle it the way they choose. As another expert on this forum explains, it's like bingo. When a number is drawn, the guy doesn't go down the aisle and mark each person's board. He calls it out (an event) and each person handles it accordingly (the subscribers handling the event).

Let's create a custom EventArgs class to suit our needs. This simple class extends EventArgs, and has a public string property called Name.
public class NameUpdatedEventArgs : EventArgs
{
    public string Name { get; set; }
}


We'll use that EventArgs class to pass our value with. Now, we must create the event itself. Inside the class definition for FirstNameForm, we'll add the folowing code:
public event EventHandler<NameUpdatedEventArgs> FirstNameUpdated;

protected virtual void OnFirstNameUpdated(NameUpdatedEventArgs e)
{
    if (FirstNameUpdated != null)
        FirstNameUpdated(this, e);
}


The first line creates the event itself. The method that follows actually triggers the event itself. It expects you to pass it a NameUpdatedEventArgs, which it will use as one of the event's parameters. So when we want our FirstNameUpdated event to be triggered, we call our OnFirstNameUpdated method.

Now that we have the code for an event up, we need to add the logic to call that event. In my example, we're going to update the value when the user clicks a button:
private void UpdateButton_Click(object sender, EventArgs e)
{
    string newFirstName = firstNameTextBox.Text;
    NameUpdatedEventArgs nuea = new NameUpdatedEventArgs();
    nuea.Name = newFirstName;
    OnFirstNameUpdated(nuea);
}


First, we're getting the new first name. Then, we create a new NameUpdateEventArgs object. Then, we assign the new first name to the Name property of the args. Lastly, we call the method that triggers the FirstNameUpdated event.

Now we're done with FirstNameForm. It's set up to broadcast its event, and needs nothing else to work.

In the DefaultForm, we need to handle the event. In this example, we are going to open the child window as soon as we open the DefaultForm, so we'll create and show the FirstNameForm in DefaultForm's constructor:
public DefaultForm()
{
    InitializeComponent();
    FirstNameForm fnf = new FirstNameForm();
    fnf.FirstNameUpdated += new EventHandler<NameUpdatedEventArgs>(fnf_FirstNameUpdated);
    fnf.Show();
}


The first line of the method is the standard method call that Visual Studio adds to every form to set up all the GUI components. The next line creates a new instance of FirstNameForm.
The next line adds an event handler**. And the last shows the window in a modeless way.

**A quick note on adding event handlers: Visual Studio will do most of the work for you. Type the beginning of the line up to the +=:

Attached Image

And Visual Studio asks you to push TAB. Push it:

Attached Image

And it finishes the line for you. But it wants you to push tab again. Do it:

Attached Image

And it creates the handler method for you as well. It really does take the guesswork and memorization out of making event handlers.

That method that VS created for us will be the code that executes every time that FirstNameUpdated is triggered. Let's fill it in:

void fnf_FirstNameUpdated(object sender, NameUpdatedEventArgs e)
{
    if (e != null && e.Name != null)
        firstNameLabel.Text = e.Name;
}


Remember that we added the name to our NameUpdatedEventArgs? That's in the variable e. First we check to make sure e and it's property are not null, then we take the Name value from e and assign it to a label.

And that's that. When we run the program, we see this before the update:

Attached Image

And after update:

Attached Image

The FirstNameDialog will not go away until you close it.

Modal

Next, we'll visit modal forms. A form is treated as modal when it is opened by the .ShowDialog method. Execution does stop at that line until the child form is closed. The ShowDialog method returns a DialogResult object.

We'll use LastNameForm as the modal dialog.

Now, modal dialogs are a bit different of a model from the other types. They're usually more limited in their focus and purpose, and execution of the parent form is blocked while they're open,\ so it's OK to tightly couple them with a parent form. To an extent. Neither form should know about the UI controls on the other, of course. That's some of the worst advice that's common on the web "make your TextBox public." Don't do that!. Instead, wrap your TextBox's Text property in a public Property. Here's how we would do this in LastNameForm (this would be added inside the class LastNameForm):

public string LastName
{
    get
    {
        return lastNameTextBox.Text;
    }
}


Now instead of dealing with an entire TextBox, we're just dealing with a string.

Now, since we don't need a way to know when the child form is closed (because ShowDialog is a blocking call), we just need to make sure to close the form when we get what we want. In this example, I'm closing the form when someone clicks a button labeled "OK":

private void OkButton_Click(object sender, EventArgs e)
{
    this.DialogResult = DialogResult.OK;
    this.Close();
}


We're setting the DialogResult to OK to let the other form know it wasn't forced closed or cancelled.

And that's all we have to do for LastNameDialog. Now we need to look at creating the dialog and retrieving it's value.

In DefaultForm, we'll launch a LastNameDialog when a user clicks a button:

private void GetLastNameButton_Click(object sender, EventArgs e)
{
    LastNameForm lnf = new LastNameForm();
    DialogResult res = lnf.ShowDialog();
    if (res == DialogResult.OK)
        lastNameLabel.Text = lnf.LastName;
}


The first line creates a new LastNameForm. The next calls it as a Modal dialog, and retrieves its response once it's closed. The next lines test to see if the DialogResult was "OK", and if so, uses the value of the LastName property for a label on the DefaultForm.

And that's really all there is when it comes to modal dialogs. Remember, this way is less involved, but Modal dialogs block execution of the main form, and you can't switch from one to the other. So you must make your choice of which to use wisely.

Here's how it looks when using it. Before clicking OK:

Attached Image

After clicking OK:

Attached Image

Note that the dialog went away when we clicked OK.

Passing a value to a new Form

Another very common related question involves passing values to a new form. One very easy way to do this is to remember that Forms are just Classes, and that all classes have constructors. Calling new Form1() is really no different than new Random() or any other class. And because this form is a class you are creating, you have control over the constructor, and its parameters.

I'll continue on with the previous example. We'll add a form called DisplayNameForm. This form is simply a display form, not an input form, so we don't have to worry about events or anything like that. But we need it to display the name, so it needs both names when it's created. Normally, when a form is created, it's created with a default constructor:

public DisplayNameForm()
{
    InitializeComponent();
}


But just because it starts that way doesn't mean it has to stay that way. Let's add some parameters to the constructor, and some assignment logic.

public DisplayNameForm(string firstName, string lastName)
{
    InitializeComponent();
    firstNameLabel.Text = firstName;
    lastNameLabel.Text = lastName;
}


Now the form requires both a first name and a last name to be created. And when it's created, it assigns those values to some labels on the form.

This, of course, changes the way we have to create and call the form. For this example, in DefaultForm, I'm showing this DisplayNameForm on a button click:

private void DisplayNameButton_Click(object sender, EventArgs e)
{
    string firstName = firstNameLabel.Text;
    string lastName = lastNameLabel.Text;
    DisplayNameForm dnf = new DisplayNameForm(firstName, lastName);
    dnf.Show();
}


The first two lines gather the names. The third is the actual creation of the new form. Notice that we're providing the names as parameters to the constructor. They match the parameters in the constructor's definition. Lastly, we show it like any other form.

Conclusion

I hope you have enjoyed this tutorial. I've tried to make it as simple as possible while still following sound design and object oriented principles.

This article was crossposted from my blog.

This post has been edited by Curtis Rutland: 07 December 2013 - 01:26 PM
Reason for edit:: fixed typos


Is This A Good Question/Topic? 24
  • +

Replies To: How to Get Values From Form1 to Form2 (or any other forms).

#2 erburrell  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 10
  • View blog
  • Posts: 145
  • Joined: 22-December 09

Posted 22 December 2010 - 10:51 AM

Very nice tutorial! Ive used the modal dialog type forms alot, but never used the eventargs to pass data back using a modaless form. Thanks for the idea!

Ed.
Was This Post Helpful? 0
  • +
  • -

#3 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 22 December 2010 - 07:59 PM

Well, I won't pretend it's my idea. It's a design concept that's been out there a long while. The problem is that a lot of programmers come from a procedural model of programming and don't make full use of events. I did; that's why I had to learn this stuff the hard way. Hopefully some people will gain some good habits from this.
Was This Post Helpful? 2
  • +
  • -

#4 tusharharlikar  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 03-February 11

Posted 04 February 2011 - 02:44 AM

can any one tell me how to pass value from second form to first one which is already open.I want value on first form when we close the second one.
i don't want to execute code on button of second form
Was This Post Helpful? 0
  • +
  • -

#5 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 04 February 2011 - 09:07 AM

Expose it as a property, like I showed for modal dialogs. You can still use Show instead of ShowDialog. You want to subscribe to Form2's FormClosed event.


Form1.cs:

public partial class Form1 : Form
{
    private Form2 form2;
    public Form1()
    {
        InitializeComponent();
        form2 = new Form2();
        form2.FormClosed += new FormClosedEventHandler(form2_FormClosed);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        form2.Show();
    }

    void form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        textBox1.Text = form2.MyValue;
    }
}


Form2.cs

public partial class Form2 : Form
{
    public string MyValue
    {
        get { return textBox1.Text; }
        set { textBox1.Text = value; }
    }

    public Form2()
    {
        InitializeComponent();
    }
}

Was This Post Helpful? 0
  • +
  • -

#6 Xeonen  Icon User is offline

  • D.I.C Head

Reputation: 8
  • View blog
  • Posts: 64
  • Joined: 01-January 11

Posted 04 February 2011 - 12:44 PM

Although I didn't understand a word from tutorial, it will save my life after I digest it to the tiniest bit of it.
Was This Post Helpful? 0
  • +
  • -

#7 MikeNewman  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-April 09

Posted 09 August 2011 - 11:50 PM

A very clear and concise explanation using textboxes.

Can you expand this to datagridviews on 2 forms named "Expenses" and Bank Account" with both opening a third form named "Calculator"? Double clicking on a cell in the datagridview of either "Expenses" or "Bank Account" opens form 3. Calculations are performed and returned to the appropriate cell in the DGV of the originating form. Doing this with a single DGV form (frmExpenses) is easy as all you have to do is return the calculated result by using a line similar to frmExpenses.datagridview1.Value(cell address row and column)= "the calulated result"

Can you pass the form name (frmExpenses or frmBankAccount) to the calculator form for use in the line that returns the calculated result? This is the bit that I have not solved.

Mike Newman
Was This Post Helpful? 0
  • +
  • -

#8 AVReidy  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 65
  • View blog
  • Posts: 431
  • Joined: 17-February 11

Posted 18 September 2011 - 03:23 PM

I had a big project all planned out (or so I thought) and then it became evident after making all of the forms that I couldn't pass data between forms. I wasn't sure where to instantiate my forms and classes so that I could control all of them.

Nice tutorial!
Was This Post Helpful? 0
  • +
  • -

#9 solomon201  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 27
  • Joined: 19-November 07

Posted 06 February 2012 - 05:49 AM

Nice tutorial very good.
But I am having a problem. I am using WPF Page based navigation and I am having trouble passing values from one page to another. How can i do this since i just have to navigate to a new Hyperlink to view another page and i need to carry along data from the previous page.

Thanks in advane for your help
Was This Post Helpful? 0
  • +
  • -

#10 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 06 February 2012 - 08:34 AM

Here are two good resources on WPF Navigation:

http://www.paulstove.../wpf-navigation
http://msdn.microsof...y/ms750478.aspx
Was This Post Helpful? 0
  • +
  • -

#11 solomon201  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 27
  • Joined: 19-November 07

Posted 06 February 2012 - 02:56 PM

@ Curtis
Thanks for the link but I am still new at this and dont really get what I am seeing there.

I have say 2 textboxes on the new page i am navigating to and i want to auto-fill it with values from say 2 other textboxes from the current page. I just need am explanation on how to do this.

Thanks
Was This Post Helpful? 0
  • +
  • -

#12 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 06 February 2012 - 03:28 PM

Unfortunately it's not as simple as "just an explanation" for that. It's a concept. I've never used WPF Navigation applications before, so I won't be as good at explaining it as the first link. I suggest trying it again.
Was This Post Helpful? 0
  • +
  • -

#13 gottaGetIt  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 09-November 13

Posted 09 November 2013 - 02:27 AM

Very very concise, detailed, and overall helpful post, Thanks alot! There are a few typos however, I think we can let you slide. The blogsphere needs more post with great structure and organization like this one!
Was This Post Helpful? 0
  • +
  • -

#14 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4314
  • View blog
  • Posts: 7,473
  • Joined: 08-June 10

Posted 09 November 2013 - 08:45 AM

You might be interested in our Learning C# series:

http://www.dreaminco...%23-start-here/

Some of them are mine, some are written by other members, but I believe they're all high-quality.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1