Just made the switch from VB6 to .NET yesterday...

LHandy

Well-known member
Joined
May 27, 2005
Messages
50
Programming Experience
5-10
RESOLVED: Just made the switch from VB6 to .NET yesterday...

I searched on this topic already and couldn't find anything that directly related to my problem. Sorry if this is a repost.

I just made the switch from VB6 to VB.NET last night and I'm having some trouble. I have searched Google, read newbie tutorials, and I just can't find a solution to a really simple problem. I have never done OOP before so this is almost like learning to write code for the very first time.

My problem is this. I have a linklabel, and inside of it is this code:

VB.NET:
Dim newAbout as New frmAbout 

newAbout.Show


Okay, so now I click the link label and the window opens fine. But if I click it again a new instance opens. That is to be expected. So I figured I'd try making it static. That solved the multiple instances problem but if I closed the form and clicked the linklabel again I got an error. Okay, strange that I can't do that but I guess I understand. I tried module level as well, which had the same problem (didn't think that was a viable solution anyway).

I just can't seem to get around this very simple thing. Also, in future projects I may not want to keep the variable in the linkclicked event because I will want to be able to control the form from other parts of the program. If anybody could show me what it is I'm missing I'd appreciate it.

Sorry for such a newbie question.

Edit: Also, I have tried it this way with no difference:

VB.NET:
 Module Module1
	Dim about As frmAbout
End Module

Private Sub llblAbout_LinkClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles llblAbout.LinkClicked
		about = New frmAbout

		about.Show()
End Sub

Same problem.
 
Last edited:
well, all I could say is "Post the code".
I can see that you instantiate class fromAbout and call its member "Show" that probably performs
PHP:
System.Diagnostics.Process.Start(http://www.website.com/)

But from all these facts i cannot claim what could be wrong, moreover i'm not sure what are you trying to do ... do you want to make it opens only ones?

Anyway, i would glad to help you out ... Cheers ;)


btw, welcome to the forum ;)
 
Last edited:
To explain it in the most simple way:

In Form1, so far I have just one linklabel that is supposed to call the .show method of Form2. When clicked, Form2 does open, but if I click the linklabel on Form1 again with Form2 still open... now I have two instances of Form2. I don't want multiple instances of Form2 and I don't necessarily want to call Form2 modally.

Code is currently this:

VB.NET:
Module Module1
	Dim newAbout As frmAbout
End Module

'In frmMain's llblAbout linklabel:
Private Sub llblAbout_LinkClicked(...event args...) Handles llblAbout.LinkClicked
	newAbout = New frmAbout

	newAbout.Show()
End Sub
 
Or you can do the same but in different way ...

PHP:
 Public Shared aboutIndicator As boolean = false 
 
Private Sub llblAbout_LinkClicked(...event args...) Handles llblAbout.LinkClicked
 If aboutIndicator = False then
   aboutIndicator = true 
   newAbout = New frmAbout
   newAbout.MdiParent = Me 'optional
   newAbout.Show()
 End if
End Sub

Cheers ;)
 
Hey, thanks for the reply. After reading the code that will obviously work. I was hoping there would be a less sloppy way of doing it than in these two examples you just posted. I'm not saying that it isn't a clean way to handle it -- I just mean that there should be a MultipleInstances boolean property to each form, to where if you set it to false you would only be able to show one instance of the form anywhere in your application. (Or directly calling the .show method from the actual form class itself rather than being forced to instantiate a whole new copy of it)

I mean, in VB6 all you had to do was frmAbout.show and no doubt about it... there was only one instance unless you instantiated a whole new copy of it.

Anyway, thanks for pointing me in the right direction! Solved my problem. Thanks for welcoming me, as well. I'm sure I'll be spending a lot of time here.
 
Hey, I like that last method best. Seems to be cleaner that way. I'll use that. You even answered my other question with the Shared keyword.
 
This is the way I would handle it:
VB.NET:
Friend Module AppManager
    Friend About As frmAbout
End Module

'In frmMain's llblAbout linklabel:
Private Sub LinkLabel1_LinkClicked(ByVal sender As System.Object, _
  ByVal e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) _
  Handles LinkLabel1.LinkClicked
    If AppManager.About Is Nothing OrElse AppManager.About.IsDisposed Then
        AppManager.About = New frmAbout()
    End If
    AppManager.About.Show()
    'in case the user had minimized the About form:
    AppManager.About.WindowState = FormWindowState.Normal
End Sub
A few things to note:
  • It isn't necessary to include the module name in the linkLabel click event (If AppManager.About Is Nothing ...). I do this for clarity, to show the entire path to the class. I feel it's makes for better programming practice.
  • Notice the Friend keyword used to declare the Module and the About variable. The Friend keyword gives application level scope, but won't allow access from outside the application. It's best to use as narrow a scope as possible.
  • Using variables declared in a module as shown will allow you "to control the form from other parts of the program"
 
LHandy said:
I mean, in VB6 all you had to do was frmAbout.show and no doubt about it... there was only one instance unless you instantiated a whole new copy of it.

no offense but it may seem like more work, but this is one of the many reasons why i'm on vb.net and not vb6

in time you really do get used to those subtle changes between the two
 
JuggaloBrotha said:
no offense but it may seem like more work, but this is one of the many reasons why i'm on vb.net and not vb6

in time you really do get used to those subtle changes between the two

Well, yes, I see the benefits of it. I just wish there were some easier way to control the instances of a form aside from writing out conditional If statements.

Speaking of that, Paszt, very nice. I wasn't aware of IsDisposed. Thanks!
 
The code that I have shown above is how VB6 would handle the call to a form, without the need to create an instance. It's just that in VB6 the code was hidden.
Since VB.NET is now Object oriented, it was decided that forms should be treated as classes and not as a special form of a class. Giving the user the ability to have more control over the way that they are used.
That being said, if you wish to mimic the way that earlier versions of Visual Basic delt with forms, you can add the following code to each form and specify, for example, Form1.DefInstance instead of Form1:
VB.NET:
Private Shared m_vb6FormDefInstance As Form1
Private Shared m_InitializingDefInstance As Boolean
Public Shared Property DefInstance() As Form1
    Get
        If m_vb6FormDefInstance Is Nothing _
            OrElse m_vb6FormDefInstance.IsDisposed Then
            m_InitializingDefInstance = True
            m_vb6FormDefInstance = New Form1()
            m_InitializingDefInstance = False
        End If
        DefInstance = m_vb6FormDefInstance
    End Get
    Set(ByVal Value As Form1)
        m_vb6FormDefInstance = Value
    End Set
End Property
If you upgrade a VB6 project, the upgrade wizard will actually add this code to each form to provide you with the default instance functionality that you were able to use in earlier versions of Visual Basic.
 
Back
Top