Question

I am updating some code from a vb6 application to VB.NET.

I have a problem that occurs when I try to open a form from the main form.

It calls this function:

Public Sub optDrawSafeFile_CheckedChanged(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles optDrawSafeFile.CheckedChanged
    If eventSender.Checked Then
        '--------------------------------------------------------------------------------
        ' JRL 11-03-06
        ' change the enables

        UpdateGUI((False))
        cboProject.SelectedIndex = frmMain.cboProjects.SelectedIndex
        SelectJob()
    End If
End Sub

And when it goes to execute this line:

cboProject.SelectedIndex = frmMain.cboProjects.SelectedIndex

It blows up and says this:

enter image description here

frmMain is declared like this:

enter image description here

How can I fix this error?

TL;DR

It is described in more detail in this video.

Was it helpful?

Solution

Short answer: change frmMain to My.Forms.frmMain.

cboProject.SelectedIndex = My.Forms.frmMain.cboProjects.SelectedIndex

Long answer:

In VB6, referencing a form by its name allowed you to access it both as a class and an instance of that class. The instance that you access in this manner is called the default instance. This is not possible in VB.NET. However, VB.NET includes a dynamically generated class, My.Forms, that provides functionality similar to that of default instances.

See http://msdn.microsoft.com/en-us/library/ms379610%28v=vs.80%29.aspx#vbmy_topic3 for more information about My.Forms and the "My" namespace.

A better and more object-oriented way to handle this, however, would be to pass the instance of the main form to the constructor of the frmAddMethod form and store it in an instance field.

So, within the class definition in frmAddMethod.vb:

Sub New(ByVal mainForm As frmMain)
     _mainForm = mainForm
End Sub

Private _mainForm as frmMain

And when you create the frmAddMethod instance from frmMain, pass in "Me" to the constructor:

Dim addMethodForm as new frmAddMethod(Me)

"Me" is the instance of the class from which a non-shared class method was called.

This will allow you to use the _mainForm class field to access the instance of the main form from non-shared methods of frmAddMethod.

*Edited to recommend My.Forms instead of DefInstance per Plutonix's comment.

OTHER TIPS

Nothing is "blowing up", your program is not crashing. Using a type name, like frmMain, where an object reference is expected is something that the VB.NET compiler allows. Specifically for the Form class, an appcompat hack for VB6 code. It is the debugger that doesn't think much of it. It merely gives you a diagnostic on your watch expression since it doesn't have the same appcompat hack as the compiler does. So doesn't know what to display.

You can use My.Forms instead to get the active form object reference. So make your watch expression:

   My.Forms.frmMain.cboProjects.SelectedIndex

Only do this when you are single-stepping the code, it will still go wrong if you use Debug + Break All to break into the program. Setting a watch expression on Me.cboProject is otherwise the obvious workaround in this specific case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top