My solution has been mischaracterized and there has been some confusion about the various possible approaches to answer this question, so I've edited my original post to compare and contrast the three major approaches discussed at length on this page.
Solution 1: Use VB.NET default form instances
Put this line after Dim mainmenu As New MainMenu
:
mainmenu.Show()
You will probably have two MainMenu forms. This is because VB allows you to reference a static instance of a form simply by using its class name. So you can just be saying i.e. MainMenu.Property = value
and it will operate on the static instance created by VB.
Try removing the line Dim mainmenu As New MainMenu
. This might be all you need to do (as long as you Show() the form) since you called your reference the same as the class name.
Solution 2: Follow the Singleton design pattern (simplified version, no thread safety)
The singleton design pattern makes sure there can only be one instance of a class. Putting this code into your MainMenu will surely cause some errors to appear on your screen.
Public Class MainMenu
' static (shared) instance of this class
Private Shared _instance As MainMenu
' function which returns the static instance
' with lazy initialization (constructor is called once GetInstance is
Public Shared Function GetInstance() As MainMenu
If _instance Is Nothing Then
_instance = New MainMenu()
End If
Return _instance
End Function
' private constructor to restrict instantiation of this class (only allowed in GetInstance)
Private Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
' all the rest of your original MainMenu code here
End Class
The way you fix the errors is by using a variable to hold a reference to the instance of MainMenu. Simply, replace mainmenu
with a variable like myMainMenu
and before you use the form, put this:
Dim myMainMenu As MainMenu = MainMenu.GetInstance()
myMainMenu.Show()
Solution 3: Create your own instance(s)
There are differences between solution 1 and solution 3 . In solution 1, you will only have one instance of the form if you use only default instances. This solution allows you to have any number of instances! You probably don't need this, but here goes...
You will make a new instance of MainMenu called myMainMenu again but this time you call the constructor directly.
Dim myMainMenu As New MainMenu()
myMainMenu.Show()
Wherever you call the form by the name mainmenu
, replace that with myMainMenu
. Did I mention that we call it myMainMenu instead of mainmenu because we don't want to use the same name as the class name? (VB is case-insensitive so mainmenu
= MainMenu
, but this is easily confusing because of the default instance. The compiler uses context to determine if we are talking about the class itself or the class' default instance...) Using the classname only works when you reference the default static instance as in solution 1.
The attractive thing about this solution is that you can have multiple instances of MainMenu alive at the same time. So you can put this after:
Dim myMainMenu2 As New MainMenu()
myMainMenu2.Show()
And voila, you have two MainMenu open. But you probably didn't need two!
Summary
Why are there so many methods?
Well, the first method was added to attract VB6 programmers to VB.NET because that was how it was done in VB6! To be accurate, it can be done this way in VB6, but some programmers with half a brain still chose to follow method 3. But the default instance method was so widespread because it was so easy for the casual programmer to use - especially all those laymen using it inside VBA!
The second method is preferred in some instances, but not in others. It is a simple implementation of the Singleton design pattern. Check out the link in Douglas Barbie's answer for a decent explanation of it and some examples in Java. It lists a good summary of all the times you'd need to use it - a logger which should only have once instance, a configuration loader, a factory or other instance generator - these are probably out of your scope, but maybe simply think about a Print dialog in Microsoft Office. There only needs to be one Print window open at a time. This is a good example of it. Does your code require this? Following the pattern allows for this behavior, but there is some additional configuration as I put in the example. If the App is simple enough, it probably doesn't need it.
The third is a quintessential example of object oriented programming (a good place to start is understanding OOP; this knowledge alone should give you the tools to solve problems like this in the future). It uses a class called MainMenu, which you created, and uses potentially more than one instance of the class, called objects. An advantage of this is that you can have two object instances of the same class, but the objects have properties with different values. Think two instances of class Car
, one has Car.Make = "Ford"
, the other Car.Make = "Chevy"
. Both cars, but they differ by property values. This differs from the first two only by the fact that you can have multiple instances. If we want to get technical, you can merge solution 1 and 3 and use the default instance and make your own instances, but this is warned against by just about everyone who discusses it (Google "VB.NET form default instance" for more on that matter).
In the end, if you are coding something on a small scale, it's whatever works reliably for you.