Nearly all technical articles recommend that when you need multiple forms in a Windows Forms application, you should add additional forms to the project and then "instantiate" the new forms. Here's an example. In Murach's "core" book on programming, Visual Basic 2010 (Read the About Visual Basic review here.), frmPayment is added to a project using "Add > New Item ..." and then instantiated with this code:
Dim paymentForm As New frmPayment paymentForm.ShowDialog()
References at the Microsoft site recommend the same thing and even this site (in an article written eight years ago) uses that code. But the fact is that you usually get identical results without explicitly instantiating the form. In other words, just replace the code above with:
The key word is, "usually". I couldn't find any references that discuss the pro's and con's of doing it one way or the other, so I decided to write one, especially since the references that I did find almost all said that not instantiating the form either didn't work at all or was not good programming practice. (But without providing any reasons.) I question whether that advice is still true. I don't believe it is.
To begin, it's necessary to have a clear understanding of what happens when you instantiate the form. (I'm calling this "explict instantiation".)
Dim InstantiatedCopy As New OriginalForm
In order for this statement to work, you have to add OriginalForm to your project in Visual Studio first. When you add a form, a new class, complete with it's own file is added named OriginalForm.vb. (Actually, several files, but Visual Studio only shows you some of them.) That file clearly shows that a new class has been added:
Partial Class OriginalForm Inherits System.Windows.Forms.Form ... Microsoft's "secret sauce" generated code End Class
When this form is instantiated, a Form object is added to your project in memory based on this class. To see the forms that are open in the project for yourself, Microsoft suggests the OpenForms method to display the form titles like this:
' My.Forms instantiation OriginalForm.Show() ' Explicit Instantiation Public InstantiatedCopy As New OriginalForm ' Change the title so we can tell which is which InstantiatedCopy.Text = "Instantiated Copy" InstantiatedCopy.Show() Try For Each f As Form In My.Application.OpenForms If Not f.InvokeRequired Then ' Can access the form directly. Console.WriteLine(f.Text) End If Next Catch ex As Exception Console.WriteLine("Error: " & ex.Message) End Try
The Output Window displays:
Form1 OriginalForm Instantiated Copy
This shows both forms because OriginalForm is implicitly instantiated (My.Forms instantiation) and explicitly instantiated as well. In a real project, this probably wouldn't happen because a programmer would do one or the other but not both. There are really very few cases where the explicit instantiation is needed but there are also some cases where it can be a problem.
Consider this code:
Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles Button1.Click Dim InstantiatedCopy As New OriginalForm End Sub Private Sub CheckNewForm_Click( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles CheckNewForm.Click Console.WriteLine(InstantiatedCopy.TextBox1.Text) End Sub
The second sub, CheckNewForm, will be flagged with a syntax error because InstantiatedCopy is local to the first sub. In order to make this work, you either have to make InstantiatedCopy global by declaring it at the class level (right after the Class statement) or ... you can simply use OriginalForm, which is already global. You can even access OriginalForm from a different code module.
This is nothing new. A form follows the same rules as any other object. The main thing that is different about a form is that Visual Studio gives you a way to create the new form objects and also generates support files for them. If you add a form to your project and then fill it with a lot of other controls, they're all available to either a New instantiated copy or to the original form. If TextBox1 contains some text, then it can be accessed both from the original form and the instantiated copy:
Dim InstantiatedForm As New OriginalForm Console.WriteLine(OriginalForm.TextBox1.Text) Console.WriteLine(InstantiatedForm.TextBox1.Text)
Some programmers call this "auto instantiation" but Microsoft doesn't use that term. Microsoft documents this behavior as a function of the My.Forms object so I call it "My.Forms" instantiation in this article. This is one of those clear differences between VB and C# because My.Forms doesn't work in C#. In C#, if you try to do the same thing, you get a syntax error. (See "Note" at the end of the article.)
On the next page, more examples show that there is quite a difference between My.Forms instantiation and explicit instantiation.