Results 1 to 40 of 48

Thread: The Definitive "Passing Data Between Forms"

Threaded View

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    The Definitive "Passing Data Between Forms"

    After seeing so many of these types of questions, I thought that coming up with one definitive answer was a good idea. Kleinma seemed to agree, so I started rooting around in the database looking at the patterns that this type of question took, and I came up with three general forms of the question. I don't know whether I have enough information to create an ultimate answer, so I thought I would put out what I have found so far, and ask people for comments and inputs:

    1) How do I transfer data between Form1 and Form2.

    This is actually not that common a question, which is probably because the answer is straightforward. There are three types of general answers.

    a)The first type would be to add public member variables to either Form1 or Form2. In either case, any code that sees either Form1 or Form2 can read the variables directly. I'll say no more about this answer, because it is quick, but not a good habit to get into.

    b)A better solution would be to add PRIVATE member variables to one of the forms, and make them accessible through properties:

    vb Code:
    1. Public Class Form1
    2.  
    3.    Private myInteger as integer
    4.  
    5.    Public Property myInt(value as integer) as integer
    6.      Get
    7.        Return myInteger
    8.      End Get
    9.      Set
    10.        myInteger = Value
    11.      End Set
    12.    End Property
    13. End Class

    This solution adds a bit more code than just making the variables Public, and there is no advantage to this technique in the above example. However, by using a property, you have some control over what is getting passed in, and how it is being dealt with. A form is a class, and a class should be the sole owner and gaurdian of its data. The class itself should control what data is accessible, and how. By using properties, you can make members ReadOnly, WriteOnly, or open to all. You can also make the protected, which affects inheritance. Furthermore, you can use the Set block to restrict input values, and can use the Get block to resolve requests for things that are otherwise improper (like asking for item 10 in a 9 element array).

    In general, you can put the property on Form1 and have Form2 go get it, or put the property on Form2 and have Form1 push the data to Form2. Which you choose depends entirely on what makes sense. If Form2 is created by Form1, then it makes sense for Form1 to fill Form2 simply because Form1 is "creating" Form2. If Form2 is independent of Form1, then it makes sense that Form2, when it is created, goes and gets the data it needs from Form1.

    c) An alternative, if Form2 is being created by Form1 is to overload the constructor (the Sub New for the form) to either accept arguments that have the data, or to go get the data from the properties of other classes, as needed. The advantage of this technique is that it is a very clean way to create the form, and can be used to FORCE the correct initialiaztion of the form. If you overload the constructor with arguments, you could change the default constructor to Private, such that the overloaded constructor is the ONLY way to create the form. By doing this, you enforce the requirement (even on yourself) that the form be called with the correct arguments. Since these arguments can be the data pieces needed by the form, this will enforce the correctness of the form.

    If you use the default instance of a form, then you can't use the overloaded constructor technique to move data to a new form. The reason for this is that the default instance uses a default constructor which takes no arguments. Therefore, if you are using the default instance, use properties.

    Having said all that, I should repeat that this form of the data transfer question is relatively rare. MUCH more common is this:

    2) I want to move data from Form1 to Form2, but when I do, the data isn't there, even though I can see it. What is wrong?

    This isn't actually a data transfer issue at all, but a fundamental misunderstanding about variables. I suspect that this problem is worse for people coming from VB6 to .NET, and for users of 2005 rather than 2003, because of the default instances in both VB6 and 2005.

    When a variable is declared:

    Dim myForm as Form1.

    That line instructs the compiler to set aside sufficient memory for an object of type Form1. No actual form is created, and the memory, if you could see it, would be nothing but garbage. You create the form when you write the word New:

    myForm = New Form1

    This tells the compiler to create a new instance of the object called Form1, and put this object in the memory called myForm, which was previously set to the size needed to hold a Form1. It is the New statement that fills the garbage memory with an actual, orderly, instance of Form1.

    The problem that people seem to be having when they ask this form of the question is that they are creating a new instance of Form1, and expecting that it will have the data that is already found in an existing instance. However, the Dim statement is telling the compiler to set aside a totally new chunk of memory, and the New statement is telling the compiler to create an entirely new instance of the object. Naturally, a totally new instance is not the same as any existing instance, so when you look at the properties of this totally new instance, they will not contain the data that was added to an existing instance. Worse, if you don't actually use New, you won't have an actual object, but just some garbage chunk of memory of the right size for the object, but not an actual object.

    The solution in this case is to use the existing instance and not create a new instance. I have not come up with any general means to do this, as it depends entirely on the specific design. A few options are these:

    a) If the other instance was created at some other, earlier, time, then there will be a line like oldInstance = New Form1. Thus, oldInstance is the instance that holds the data you want, so don't create a new instance like dim f1 as New Form1, but use oldInstance instead. This may not be easy, because the existing program design might well have oldInstance delared in such a way that it is inaccessible to another form (it might be a private member variable, or it might be declared with function scope rather than class scope). The only way to fix this would be through changing the design so that the oldInstance is accessible, or by a fairly hideous workaround of putting the data from oldInstance into a different class that is visible to the instance of Form2, and getting the data from that intermediate class.

    b) If Form2 is being created from Form1 (e.g. a button click event creates the instance of Form2), then just add a property to Form2, and have Form1 populate it as described for the first form of the question, rather than having Form2 try to go and get the data from Form1 once it has been created.

    3)Passing data from Parent form to Child form in an MDI environment?

    This form of the question is pretty common, but takes many forms, as people seem to have different ideas of what is the parent and what is the child. Furthermore, I don't see any particular pattern to these questions, nor the answers to them. Also, I have no experience with MDI environments. Therefore, I need somebody else's input as to whether there is some comprehensive answer to this type of the question.

    Ok, there's my first pass, with minimal editing. I'd like some edits, suggestions, and etc.
    Last edited by Shaggy Hiker; May 3rd, 2007 at 04:33 PM.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width