3.13. Communicate Between Forms
In previous versions of .NET, you were responsible for tracking every open form. If you didn't, you might unwittingly strand a window, leaving it open but cut off from the rest of your application. VB 2005 restores the beloved approach of VB 6 developers, where there's always a default instance of your form ready, waiting, and accessible from anywhere else in your application.
Note: VB 2005 makes it easy for forms to interact, thanks to the new default instances. This feature is a real timesaverand a potential stumbling block.
3.13.1. How do I do that?
To access the default instance of a form, just use its class name. In other words, if you've created a form that's named (unimaginatively) Form1, you can show its default instance like this:
This automatically creates an instance of Form1 and then displays it. This instance of Form1 is designated as the default instance.
To communicate between forms, you simply add dedicated public methods. For example, if Form1 needs to be able to refresh Form2, you could add a RefreshData( ) method to Form2, like this:
Public Class Form2 Private Sub RefreshData( ) MessageBox.Show("I've been refreshed!") End Sub End Class
You could then call it like this:
This calls the RefreshData( ) method of the default instance of Form2. The fact that RefreshData( ) is a method you added (not an inherited method, like the Show( ) method) makes no difference in how you use it.
You can also get at the forms using the My collection. For example, the code above is equivalent to this slightly longer statement:
You can always access the default instance of a form, even if it isn't currently visible. In fact, .NET creates the default instance of the form as soon as you access one of its properties or methods. If you only want to find out what forms are currently open, you're better off using the My.Application.OpenForms collection. Here's an example that iterates through the collection and displays the caption of each form:
For Each frm As Form In My.Application.OpenForms MessageBox.Show(frm.Text) Next
This handy trick just wasn't possible in earlier versions of .NET without writing your own code to manually track forms.
3.13.2. What about...
...potential problems? Conveniences such as default instances come at a price. In this case, you don't need to worry about wasted memory or any performance slowdown, since .NET is clever enough to create the forms as you need them. The real problem that you might face results from the fact that default instances confuse the concepts of classes and objects, making it all too easy to accidentally refer to different instances of the same form in different parts of your application.
Note: You can also get a reference to the application's startup form using the My.Application.StartupForm property.
For example, imagine you use this code to show a form:
Dim FormObject As New Form1 FormObject.Show( )
In this example, the form you've shown is an instance of Form1, but it isn't the default instance. That means that if another part of your code uses code like this:
it won't have the effect you expect. The visible instance of Form1 won't be refreshed. Instead, the default instance (which probably isn't even visible) will be refreshed. Watch out for this problemit can lead to exasperating headaches! (In all fairness to .NET, this isn't a new problem. Visual Basic 6 developers encountered the same headaches when creating forms dynamically. The difference is that Visual Basic 6 developers almost always rely on default instances, while .NET developersuntil nowhaven't.)