Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / C#
Article

Passing Data between Windows Forms

Rate me:
Please Sign up or sign in to vote.
4.63/5 (86 votes)
27 Jan 20076 min read 317.1K   13.6K   231   49
Passing Data between Windows Forms

Introduction

This article provides a simple example of using delegates and events to transfer data between Windows forms. The example provided contains three separate forms; the main form interacts with the other two forms by responding to events generated by instances of the other two forms.

In order to communicate between the forms, each of forms capable of generating an event contains declarations for a delegate and an event. A delegate may be thought of as a type safe function pointer and delegates are associated with methods that bear the same signature. An event is a device used to notify listening objects that something has happened; events are associated with a delegate when instantiated.

Through the use of delegates and events it is possible to communicate values between forms in a Win Forms application.

Figure 1. Using Delegates and Events to Communicate Between Forms

Getting Started.

There is a single solution included with this download, the solution contains a Win Forms project called “PassBetweenForms”; this project contains three forms, one main form that creates instances of the other two forms and responds to events raised by the instances of those two forms.

For the sake of an example, the main form (frmMain) contains an area used to contain an identity (first, middle, and last name) and an area used to display an address (street, city, state, and zip code). The values for these areas are displayed on the form but the form does not allow the user to enter the text directly into the form.

In order to set the values associated with the ID or Address sections of the main form, the user must click on a “Set” button which creates an instance of either the “frmID” form or the “frmAddress” form. When data is entered into and submitted from either of these forms, the main form listens for an update event and then loads the information from either of the other two forms into the main form’s associated text boxes.

Figure 2. Solution Explorer

Code: The Address Form

Rather than starting with the main form, first take a look at the Address form. The Address form contains three parts that make communication with the main form possible. Those parts are the delegate and event declarations and the declaration of a class used to define the content of the event arguments made available to the event listener when the event is fired.

The class declaration contains only the default imports and after the imports, the delegate and event are declared:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PassBetweenForms
{
    public partial class frmAddress : Form
    {
        // add a delegate
        public delegate void AddressUpdateHandler(
            object sender, AddressUpdateEventArgs e);

        // add an event of the delegate type
        public event AddressUpdateHandler AddressUpdated;

        public frmAddress()
        {
            InitializeComponent();
        }
    }
}

The signature of the delegate is pretty standard in this example, it contains the sender as an object and the event arguments; it is possible to use different signatures and return types, the approach used here is just a convenient way to return several values when an event is raised. The “AddressUpdateEventArgs” is the class used to provide a customized argument list to the project. This class inherits from the “EventArgs” class and contains properties used to capture the values provided on the form and to make them available to the listener when the event is fired.

The next bit of code in this class is used to handle the OK button’s click event. When the OK button is clicked from this form, all of the text box values contained in the form are passed to string variables. Once the value have been collected, the custom event argument class is instantiated and, through its constructor, passed each of the values captured from the form. The address updated event is then fired and the event arguments are passed on to the listeners with the event; once the event is raised, the form is closed by calling the dispose method:

C#
private void btnOkay_Click(object sender, EventArgs e)
{
    // this button click event handler will raise the 
    // event which can then intercepted by any listeners

    // read the textboxes and set the member
    // variables
           
    string sNewStreet = txtStreet.Text;
    string sNewCity = txtCity.Text;
    string sNewState = txtState.Text;
    string sNewZipCode = txtZipCode.Text;
           
    // instance the event args and pass it each value

    AddressUpdateEventArgs args = 
        newAddressUpdateEventArgs(sNewStreet,  
        sNewCity, sNewState, sNewZipCode);
           
    // raise the event with the updated arguments

    AddressUpdated(this, args);
           
    this.Dispose();
}

The second class contained in the code file is the “AddressUpdateEventArgs” class. This class is pretty straight forward; it contains a set of local member variables used to capture the address information collected from the form and some public read only properties used to access those values. The class constructor accepts all of the arguments necessary to populate the event argument properties. The code is as follows:

C#
public class AddressUpdateEventArgs : System.EventArgs
{
    // add local member variables to hold text
    private string mStreet;

        private string mCity;
        private string mState;
        private string mZipCode;

        // class constructor
        public AddressUpdateEventArgs(string sStreet, 
                string sCity, string sState, 
                string sZip)
        {
            this.mStreet = sStreet;
            this.mCity = sCity;
            this.mState = sState;
            this.mZipCode = sZip;
        }

        // Properties - Viewable by each listener
        public string Street
        {
            get
            {
                return mStreet;
            }
        }

        public string City
        {
            get
            {
                return mCity;
            }
        }

        public string State
        {
            get
            {
                return mState;
            }
        }

        public string ZipCode
        {
            get
            {
                return mZipCode;
            }
        }
}

Code: The ID Form

I am not going to describe the ID form as it is essentially the same as the Address form with the only exception being that it is used to capture the ID related information instead of the address information. The code for the ID form class is as follows:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PassBetweenForms
{
    public partial class frmID : Form
    {
        // add a delegate

        public delegate void IdentityUpdateHandler(
                object sender, IdentityUpdateEventArgs e);

        // add an event of the delegate type
        public event IdentityUpdateHandler IdentityUpdated;

        // default constructor
        public frmID()
        {
            InitializeComponent();
        }

        // close the form without raising the event
        private void btnCancel_Click(object sender, 
                                     EventArgs e)
        {
            this.Dispose();
        }

        // raise the event
        private void btnOkay_Click(object sender, 
                                   EventArgs e)
        {
            // this button click event handler will raise
            // the event which can then intercepted by any
            // listeners
            // read the textboxes and set the variables
           
            string sNewFirst = txtFirstName.Text;
            string sNewMiddle = txtMiddleName.Text;
            string sNewLast = txtLastName.Text;
           
            // instance the event args and pass it each
            // value

            IdentityUpdateEventArgs args = 
                newIdentityUpdateEventArgs(sNewFirst,
                sNewMiddle, sNewLast);
           
            // raise the event with the updated arguments
           
            IdentityUpdated(this, args);
            this.Dispose();
        }
    }

    public class IdentityUpdateEventArgs : System.EventArgs
    {
        // add local member variable to hold text
        private string mFirstName;
        private string mMiddleName;
        private string mLastName;

        // class constructor

        public IdentityUpdateEventArgs(string sFirstName, 
            string sMiddleName, string sLastName)
        {
            this.mFirstName = sFirstName;
            this.mMiddleName = sMiddleName;
            this.mLastName = sLastName;
        }

        // Properties - Accessible by the listener
        public string FirstName
        {
            get
            {
                return mFirstName;
            }
        }

        public string MiddleName
        {
            get
            {
                return mMiddleName;
            }
        }

        public string LastName
        {
            get
            {
                return mLastName;
            }
        }
    }
}

Code: Main Form.

The main form of the application is used to display the information originating from the ID and Address forms. The form contains a set of ID and a set of Address related text boxes that cannot be edited directly from the form. The form contains two buttons used to open an instance of either the Address or ID forms; information entered into those two forms is made available to the main form when the update event is fired from either of those forms.

The class is initialized with all of the default settings in terms of class library imports; the first part of the code is as follows:

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace PassBetweenForms
{
    public partial class frmMain : Form
    {
        // default constructor
        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, 
                                  EventArgs e)
        {
            // nothing to do
        }
    }
}        

The first interesting bit of code in the main form is the button click event handler used to respond to a request to set the identity information; that code is as follows:

C#
private void btnSetName_Click(object sender, EventArgs e)
{
    frmID f = newfrmID();
           
    // Add an event handler to update this form
    // when the ID form is updated (when
    // IdentityUpdated fires).

    f.IdentityUpdated += new frmID.IdentityUpdateHandler(
                                IdForm_ButtonClicked);
           
    f.Show();
}

In this bit of code, a new instance of the ID form is created. Next, the event used to notify the listener that the ID information has been updated is associated with event handler contained in this, the main form class. After this association is defined, the form is displayed.

The main form event handler associated with the ID form event is as follows:

C#
// handles the event from frmId
private void IdForm_ButtonClicked(object sender, 
                IdentityUpdateEventArgs e)
{
    // update the forms values from the event args
    txtFirstName.Text = e.FirstName;
    txtMiddleName.Text = e.MiddleName;
    txtLastName.Text = e.LastName;
}

This handler accepts the custom event argument list passed when the event is raised and the values contained in the event arguments are used to update the form’s fields in response the event.

The next blocks of code are used to perform the same functions as the last two handlers only for the address information instead of the ID information:

C#
private void btnSetAddress_Click(object
                                 sender, EventArgs e)
{
    frmAddress f = newfrmAddress();

    // Add an event handler to update this form
    // when the Address form is updated (when 
    // AddressUpdated fires).
    
    f.AddressUpdated += new frmAddress
        .AddressUpdateHandler(AddressForm_ButtonClicked);
           
    f.Show();
}

// handles the event from frmAddress
private void AddressForm_ButtonClicked(object sender, 
                            AddressUpdateEventArgs e)
{
    // update the forms values from the event args
    txtStreet.Text = e.Street;
    txtCity.Text = e.City;
    txtState.Text = e.State;
    txtZipCode.Text = e.ZipCode;
}

The last bit of code is merely a click event handler for the exit button:

C#
private void btnExit_Click(object sender, EventArgs e)
{
    Application.Exit();
}

That concludes the description of all of the code used in this example.

Summary.

The article shows one approach to using events and delegates to pass data between forms through the use of custom event arguments. There are other ways to perform the same tasks but this is a convenient and easy approach to use. Delegates may be defined with different signatures and return types and for that reason is it possible to devise a number of alternative approaches to passing data between forms.

This example showed how the approach can be used to pass multiple values between forms simultaneously, however, one could use the same approach to pass a single value or values of different types just as easily.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Praiseperfectly demo delegate vs event Pin
Southmountain19-Mar-22 10:48
Southmountain19-Mar-22 10:48 
GeneralMy vote of 5 Pin
Member 129308882-Jan-17 1:18
Member 129308882-Jan-17 1:18 
GeneralMy vote of 5 Pin
Walter Heyck10-Dec-14 10:24
Walter Heyck10-Dec-14 10:24 
QuestionBrilliant work. Very well put Pin
Member 1069047712-May-14 9:03
Member 1069047712-May-14 9:03 
QuestionExcelent!! Post .... Pin
ManishSharma_dotnet14-Apr-14 1:46
ManishSharma_dotnet14-Apr-14 1:46 
GeneralMy vote of 5 Pin
narla.venkatesh12-Feb-14 22:07
narla.venkatesh12-Feb-14 22:07 
GeneralMy vote of 5 Pin
Stefan Bischof17-Jul-13 1:53
Stefan Bischof17-Jul-13 1:53 
GeneralMy vote of 5 Pin
terrybozzio26-May-13 6:42
terrybozzio26-May-13 6:42 
GeneralMy vote of 5 Pin
bestdealex16-May-13 1:51
bestdealex16-May-13 1:51 
QuestionHigh 5 Pin
GreatBigYetti22-Mar-13 9:21
GreatBigYetti22-Mar-13 9:21 
GeneralMy vote of 5 Pin
m0nst3r.nva27-Nov-12 16:21
m0nst3r.nva27-Nov-12 16:21 
GeneralMy vote of 5 Pin
Amit.Bhargab18-Aug-12 21:12
Amit.Bhargab18-Aug-12 21:12 
Questionre creating instances of Secondary Forms in private methods of a Main Form Pin
BillWoodruff29-Jul-12 18:57
professionalBillWoodruff29-Jul-12 18:57 
GeneralI really like this post Pin
shalabh gupta20-Mar-12 7:46
shalabh gupta20-Mar-12 7:46 
SuggestionThe easier way to do that Pin
Max141419-Mar-12 5:56
Max141419-Mar-12 5:56 
GeneralIt is perhaps a wrong way! Pin
Amit.Bhargab18-Aug-12 21:27
Amit.Bhargab18-Aug-12 21:27 
GeneralRe: The easier way to do that Pin
SlowMo ShiOri11-Mar-14 10:02
SlowMo ShiOri11-Mar-14 10:02 
GeneralMy vote of 5 Pin
Ganesh Nellaiappan Rajan14-Mar-12 20:29
Ganesh Nellaiappan Rajan14-Mar-12 20:29 
GeneralMy vote of 5 Pin
provn20-Feb-12 11:36
provn20-Feb-12 11:36 
GeneralMy vote of 5 Pin
sandy1710-Apr-11 22:59
sandy1710-Apr-11 22:59 
GeneralI got problem when I implemented it to my project Pin
impauls23-Aug-10 21:43
impauls23-Aug-10 21:43 
GeneralRe: I got problem when I implemented it to my project Pin
impauls23-Aug-10 21:45
impauls23-Aug-10 21:45 
Generalwhile implementing the same in managed c++, everything went fine except ... [modified] Pin
cooolguy_0095-Mar-10 22:27
cooolguy_0095-Mar-10 22:27 
GeneralRe: while implementing the same in managed c++, everything went fine except ... [modified] Pin
Philippe Mori22-Jan-13 12:53
Philippe Mori22-Jan-13 12:53 
GeneralExcelent!! Pin
RICARDO MARCONE7-Feb-10 4:28
RICARDO MARCONE7-Feb-10 4:28 

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.