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

23 comments:

  1. Bonnie,
    Your approach to passing data between forms looks good... I have tried COUNTLESS times using examples form many websites on how to do this and I have almost come the conclusion that is is NOT possible. There is always something wrong, all I want to do is click a button on form1 and sent textbox data from from1 to a textbox on form2.
    Then while both forms are open, click a button on form2 and send it to a textbox on form1.
    Sounds easy enough... but nothing I have tried works.
    Any help for this old programmer would help.
    Thank You Very Kindly,
    Jim

    ReplyDelete
    Replies
    1. look here:

      http://www.c-sharpcorner.com/article/passing-data-between-windows-forms/

      Delete
    2. Replying to "Unknown" about your link to the c-sharpcorner article (using events and delegates). You must have missed the very last part of my blog post: I updated it to post a link to a follow-up to this post, and guess what ... that's where I'm also using events and delegates (http://geek-goddess-bonnie.blogspot.com/2012/12/passing-data-between-forms-redux_31.html) ... as you can see, I wrote this follow-up post almost 4 years ago. So, you're a little late to the party, but thanks for the link anyway. Someone else may find it useful (but I prefer my own blog post). ;0)

      Delete
  2. Hi Jim,
    As I said in the first paragraph, you could use one of these approaches, or combine several of them. Which have you tried to do? Can you post some of your relevant code here in a comment? (or a link to your code snippets posted elsewhere...)

    Sorry for the way these code snippets don't copy/paste very nicely. I have since found a better way to post code snippets on my blog, but haven't gone back to my old posts yet to retro-fit them.

    ReplyDelete
  3. Thanks for the reply Bonnie,
    you are the first person that is trying to help me. I will post my feeble attempt in a few minutes.

    Thanks Very Kindly,
    Jim

    ReplyDelete
  4. Sent code text via email
    Jim

    ReplyDelete
  5. I got your emails Jim ... I was out working in the yard and now it's almost dinner time, but I'll see if I can squeeze in a look at your code before dinner. If not, I'll try to get to it after dinner/movie or first thing tomorrow morning.

    ReplyDelete
  6. Hello Bonnie

    You've said at MSDN forum it's possible to pass dataset to another form by one of these ways and then use visual tools.
    I can't understand, how is it possible to pass dataset at runtime, and before that, uset it at design time and work on it by visual tools?

    Thanks,
    Amir

    ReplyDelete
  7. Hi Amir,

    I don't understand what you don't understand! ;0) Add your DataSets to both your Forms in the normal manner that you've already done, that way you can use the visual tools. But, at runtime, you're passing an instance of the DataSet from one form to the other via one or more of the approaches outlined in my post.

    Try to play with it a bit and see what you can come up with, following my guidelines. If you still are getting stuck, go back to the thread on the MSDN forum and post some of your code (the part that you get stuck on). Don't post it here --- the blog comments don't format code so it's very hard to follow, plus I'd rather help you out on the MSDN forum where it may help others as well.

    ReplyDelete
  8. Hello Bonnie,
    Can you give an example of how to pass a variable from a non-form cs file to a form file? None of these options worked for me with my slight modifications, but maybe I'm doing it wrong. I want to pass a variable which is first initialized to null and later changed (so public static string myID) to form.cs using the updated value. It would be really helpful as I can't find anything specific to this problem. Thanks in advance,
    susanna

    ReplyDelete
  9. Susanna, I'm so sorry that I missed your comment and question! You posted it almost a month ago! I don't know how I missed it. Sorry!!

    If you haven't figured it out yet and still would like some help/advice, perhaps you can send me a brief email with some code snippets showing what you're trying to do. You can't really post anything like code in a comment, there's no formatting so it would be very hard to follow, but I don't mind an email.

    ReplyDelete
  10. Hello sir, i have issue like i'm using two forms.i'm displaying number in one form using caller id.
    from main form i'm sending number to another form.
    problem is form number keeps on increasing whenever a new call.
    if i close the form on ring stop and again there is a incoming call it raises exception like cant open disposed object.
    how i need is there should be only one form which displays phone number

    ReplyDelete
    Replies
    1. Hello Srikesh -- without seeing your code, I can't say for certain, but it sounds like you could benefit from using a Forms Handler. Take a look at another one of my blog posts to see if it can help. http://geek-goddess-bonnie.blogspot.com/2012/04/forms-handler.html

      Delete
    2. Hello Sir? In "English, Sir refers to a male", "Mrs, Miss, Ms., Madam refers to a person that is female.

      Delete
    3. Yeah, I'm definitely not a "Sir" ;0)

      Delete
    4. Blame on google translate D:

      Delete
  11. Hello Bonnie,

    U GO Gurl. This is the first time that I been to your site, and I like the way that you explain Passing Data between forms. In your opinion, can I also use the Observer (Behavioral) design pattern to do the same?

    Thanks
    Leon

    ReplyDelete
    Replies
    1. Hi Leon,

      Well, in my third example where I show using an interface ... that could also have been accomplished using a delegate/event in Form1 that the MainForm could have "subscribed" to ... that's basically a simplified version of an Observer pattern I suppose. At the time I wrote this blog post, I was trying to "keep it simple", but I probably should have added that additional method of accomplishing this task.

      Delete
    2. Hello Bonnie,

      Thank you for your prompt reply. You gave me clarification of how to architectually implement the solution. Have a Happy New Year!

      Thanks again,
      Leon

      Delete
    3. You're welcome, Leon. Glad I could help. Happy New Year to you too!

      Delete
  12. For anyone interested, I've expanded this blog post to include another example, utilizing delegates/events. Take a look at the latest post, http://geek-goddess-bonnie.blogspot.com/2012/12/passing-data-between-forms-redux_31.html

    ReplyDelete
  13. Hi Bonnie, It's 2:15am and I am extremely grateful to have found your site.

    You are fabulous!

    ReplyDelete
    Replies
    1. What are you doing up at 2:15am? I was sound asleep!

      Thanks for checking it out and I hope it helped you solve your problem!

      Delete