Sunday, January 30, 2011

Passing Data Between Forms

There are several different approaches one could make to "pass" information, such as a DataSet, from one Form to another. I see this question asked a lot on the forums, so here's a quick summary. You could use one of these approaches, or combine several of them so that the developer has the flexibility to use whichever approach is appropriate. I'm going to show 3 different solutions to the problem:

First, let's assume we have a MainForm, and it instantiates and shows Form1, and needs to pass a DataSet to it.

1) Form1 can have a DataSet parameter in its constructor:

public class Form1 : Form
{
private DataSet oData;
public Form1(DataSet ds)
{
this.oData = ds;
InitializeComponent();
}
}

// called from MainForm like this:
Form1 oForm = new Form1(this.dsCustomer);
oForm.Show();

2) Form1 can expose its DataSet field as a public Property:

public class Form1 : Form
{
public DataSet oData {get;set;}
public Form1()
{
InitializeComponent();
}
}

// called from MainForm like this:
Form1 oForm = new Form1();
oForm.oData = this.dsCustomer;
oForm.Show();

3) Another option is to use Interfaces. For example, say that your Form1 allows the user to make some changes to the data in the DataSet and you'd like to have MainForm automatically reflect those changes ... even while you're still working in Form1.

First, let's define the Interface:

public interface IDisplayCustomer
{
CustomerDataSet dsCustomer {get;set};
void DisplayCustomer();
}

MainForm would then be defined like this:

public class MainForm : Form, IDisplayCustomer
{
public CustomerDataSet dsCustomer {get;set;}
public void DisplayCustomer()
{
// code here to do stuff with this.dsCustomer
}

...

// then code elsewhere to instantiate and show Form1:
this.dsCustomer = new CustomerDataSet(); // or other code to fill the dataset
Form1 oForm = new Form1(this);
oForm.Show();
}

And Form1 would look like this:

public class Form1 : Form
{
private CustomerDataSet oData;
private IDisplayCustomer CallingControl;

public Form1 (IDisplayCustomer callingControl)
{
this.CallingControl = callingControl;
this.oData = callingControl.dsCustomer;
}

public void DoStuff()
{
// code to do stuff with this.oData
...
// and then redisplay in calling form
this.CallingControl.DisplayCustomer();
}
}

UPDATE:
After getting asked about this a lot, I've decided to add a 4th idea to be considered, expanding on the above 3rd example, which used an Interface. See my new post about that here: Redux