Introduction to Nullable Types in VB.NETVB.NET Interview Questions #2

How To Pass Data Between Forms in VB.NET

September 28th, 2007

Using overloading to pass dataA common question that comes up rather often in VB discussion forums is how to pass data between forms. One of the common solutions offered are to use global variables in one way or another, for example, creating a module specifically for holding these values. These methods have all the typical problems with associated with globals. Another common strategy is to make the desired data available via properties on the forms. This can work in some cases but also can lead to undesirable interdependencies between forms. However, there is another approach that is often overlooked.

This article is about this overlooked strategy, overloading the New, Show or ShowDialog methods of forms. The reason this gets overlooked is that it isn’t obvious, particularly to someone who is new to programming or those who’ve transitioned from VB6. Forms get thought of as a special case because they contain a lot of generated code. But, actually, behind the scenes, they’re just another class in the application. And, like other classes, we can adapt them to our needs by overloading their base methods.

New

As with other classes with no explicit New method, a parameter-less New method of a form is automatically generated by the .NET compilation process. If we want to add our own overload method, we just add it to the code for it to our form. Here’s what it should look like:

Public Sub New(ByVal customerOrder As Order)
    Me.InitializeComponent()
    LoadOrder(customerOrder)
End Sub

In this example, we’re passing in an order object to our new form. Note that we call the InitializeComponent method first to create the controls on the form. This method is generated by VB.NET and is located in the [form name].Designer.vb file that contains a partial class definition for our form. Once the controls are created, we can then call our routine to load data into the controls.

When you define your own New method you will lose the default parameter-less New method and thus lose the VB.NET created default instance. To restore the default instance, add your own Public Sub New() as shown here:

Public Sub New()

    ' This call is required by the Windows Form Designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.

End Sub

In Visual Studio, if you just type in the first line and press enter the rest will be generated for you. If you don’t add this routine, you will need to explicitly create instances of the form using your New method as in this example.

Dim frmCustomerOrder As New frmOrder(CurrentOrder)

You can use this way to insure that the form is properly loaded with data before it is displayed.

Show

Show, as you probably know, displays the form modelessly and does not return a value. This function comes with one overload which allows you to specify the owing window/form. To continue our example, let’s add a Show method that takes our order object.

Public Overloads Sub Show(ByVal customerOrder As Order)
    If customerOrder Is Nothing Then
        'load up order defaults
    Else
        'load from parameter
    End If
    MyBase.Show()
End Sub

Notice at the end we call the form’s base class to show the form. If you don’t have this line, then the form will not be displayed.

While the stock methods don’t return a value, did you know that you can write a version of this method that returns a value? You can. Here’s an example:

Public Overloads Function Show(ByVal OrderID As Guid, ByVal viewOnly As Boolean) As Boolean
    If LoadCustomerOrder(OrderID) Then
        SetupControls(viewOnly)
        MyBase.Show()
        Return True
    Else
        Return False
    End If
End Function

In this example, we return a True if the order is found and the form is loaded but a False if the order ID isn’t found. Remember that processing doesn’t stop at the MyBase.Show() to wait for user input but continues onward.

ShowDialog

ShowDialog shows the target form modally and, in its built-in methods, it returns a Windows.Forms.DialogResult value. Here’s an example of overloading it

Public Overloads Function ShowDialog(ByRef newCustomerOrder As Order) As Windows.Forms.DialogResult
    newCustomerOrder = New Order
    'load up order defaults
    Return MyBase.ShowDialog()
End Function

In this case we’re passing in an order object by reference so that the dialog can modify it and return it and we’re returning a DialogResult like the other overloads. Also, just like with the show method, we need to call the base class to show the dialog.

Note, however, that we don’t need to return the DialogResult value, we can return anything we want, as seen in this code that returns an order object.

Public Overloads Function ShowDialog(ByVal orderID As Guid) As Order
    Dim ExistingCustomerOrder As New Order(orderID)
    'load up order defaults
    If ExistingCustomerOrder.OrderDetail IsNot Nothing Then
        If MyBase.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Return ExistingCustomerOrder
        Else
            Return Nothing
        End If
    Else
        Return Nothing
    End If
End Function  

It is probably best for consistency in most cases to return the same value as the default methods though.

That’s how you can pass values around between forms without having to use global variables (or work-alikes) or properties. Let me know if you have any questions, additions, or corrections by leaving me a comment.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Entry Filed under: Tip Sheets, VB.NET Tutorials


Rate This Article:

Not That GoodCould Be BetterOKGoodGreat (18 votes, average: 4.61 out of 5)
Loading ... Loading ...

16 Comments Add your own

  • 1. Paul mason  |  December 12th, 2007 at 7:46 am

    Hi, the article explains this concept very well so thank you.
    The only problem that i’m having is that i keep getting Too many arguments to ‘Public Sub Show()’.
    Any ideas what might be causeing that?
    I’ve used the same code that you used above.
    Thanks
    Paul.

  • 2. jfrankcarr  |  December 12th, 2007 at 2:24 pm

    Hi Paul,

    Without seeing your code, it’s hard to tell. I’d guess that the overload isn’t coded correctly so the compiler isn’t seeing it. That’s the first place I’d look if I was debugging the problem in my code.

  • 3. George  |  December 14th, 2007 at 1:14 pm

    Same problem: Too many arguments to “Public Sub Show()”

  • 4. George  |  December 14th, 2007 at 1:34 pm

    Okay… this code goes into the second form, the form where the data will be displayed. Now it works.

    Public Sub New(ByVal customerOrder As Order)
    Me.InitializeComponent()
    LoadOrder(customerOrder)
    End Sub

  • 5. GoWin  |  January 4th, 2008 at 12:08 am

    How to pass FormId and ControlID as paramenter to other Class in .NET

  • 6. il beppe  |  January 8th, 2008 at 9:54 am

    very good, nice technics the overload of the show method. Txs

  • 7. Paul  |  April 14th, 2008 at 7:46 am

    I’m trying to load a combo box and a list box in a form from code in a module but the data never gets there. Form-to-form works ok, it’s only module to form that doesn’t. Any ideas?

  • 8. jfrankcarr  |  April 14th, 2008 at 8:12 am

    Hi Paul,

    Without seeing the code it’s difficult to tell exactly what’s going wrong. Typically you’ll see this kind of thing happen when either a new object/control instance is created or a new array or dataset is created accidentally. Creating objects in different threads can also cause this to happen.

    The best thing to do is just walk through your code to see if there is any place where you might be accidentally initializing an object. If nothing stands to you, debug it and step through it. You’ll probably find the culprit lines of code when you do that.

  • 9. Gina Cresse  |  April 17th, 2008 at 7:05 pm

    Great article. I’ve used your method with much success. Now, though, I’ve run into a problem and I wonder if you have an answer. I’ve added the arguments to the Sub New sub in a form that contains several Public subs that get called from other forms.

    For example: In Form1 I have code that calls a public Sub in Form2, but once I changed Form2 to accept arguments, I can no longer access those public subs in Form2 from Form1. I was able to solve that (sort of) by declaring the public subs as Shared, but that has caused a problem when the Public Shared sub is showing Form3. It used to create a new instance of Form3 each time, but now it opens only 1 Form3 and shares it between Form1 and Form2, which I don’t want.

    I guess my question is, why do I lose the ability to call Form2.SomePublicSub from Form1 after I change Form2 to accept arguments?

    Thanks for a great article. I give it a 10+.

  • 10. Gina Cresse  |  April 17th, 2008 at 8:27 pm

    Followup: Regarding the above post, I discovered my problem was because I was passing the arguments to the Public Sub New in the designer.vb file instead of adding a Public Sub New(arguments) to the form.vb file. Once I re-arranged that code, everything works perfectly now.

    Thanks!

  • 11. Brian in UK  |  August 28th, 2008 at 11:24 am

    I have been using the new method to pass data into forms for some time.

    I also use the arguments passed in to set up the form to edit a record or add a new one. So if i pass CustomerID with 0 then the form go’s into an add new mode.

  • 12. Ignacio From Mexico  |  November 25th, 2008 at 9:59 pm

    Thanks a lot. With your dossier I have solved all my problems with “dialog ” emulated forms. Very concise and clear

  • 13. Farhan  |  April 27th, 2009 at 10:40 pm

    Hi, thanks for the article. I am a newbie to programming.it would be of great help if you make a demo project with source code available,so that a person like me can get a very clear picture of the solution you suggested.Also if you have the other way around soultion available to compare with the solution you suggested.

    Thanks

  • 14. MUDO  |  May 18th, 2009 at 3:19 pm

    Hi.

    I would like to know how to pass variable to form before creation of this form. I want to pass object which represents important data and then to perform some actions on form with this object. So I want to have form for user and for visual purpose no for variables and performing actions. For this purpose I have mentioned object.

    I dont know how to pass variable to form which is Startup form. I want to have SDI application and this form must be as Startu form. One solution is to create second from, set it as Startup form and call my first form.

    In C# it is simple - there is Program.cs and Application.Run so I can call Application.Run(new frmC_Main());

    But VB? There are Application.myapp and Application.Designer.vb files, but how to call something similar to C#?

    Thx in advance.

    …MUDO…

  • 15. Marc  |  July 16th, 2009 at 11:02 am

    I was wandering if this technique will work for Web forms also

  • 16. Robert  |  September 14th, 2009 at 3:50 am

    Very well, thank you. I just wonder if the couold be some explanation added as to where exactly in code we add those overloads. On the side of calling procedure or called function?

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Visit Me At My New Site, Programming In C#

Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives