tags:

views:

28

answers:

2

When an instantiated class calls a method in the parent form class, VB.NET starts a new instance of the form class instead of calling the method on to the active one!

How do I tell it that I have just one instance of my form class, or that I don't want to create a new instance of the form and just call the method on the already active form?

+1  A: 

Okay, found the answer. You have to access your form via the OpenForms collection.

CType(My.Application.OpenForms.Item("Form1"), Form1).myMethod()
Jenko
Ha, ok, accept your own answer!
o.k.w
+2  A: 

This is a classic issue when you use threading. The form instance variable has the <ThreadStatic> attribute. Which causes it to create a new instance of the form when your code runs in a different thread. This can be hard to detect, the form isn't visible since you didn't call its Show() method. Not that it would work anyway, the thread isn't pumping a message loop.

Your workaround has problems of its own. There's a nasty bug in the Application.OpenForms implementation, it loses track of forms when their window gets recreated. Try this code for example:

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Me.ShowInTaskbar = False
    MessageBox.Show(String.Format("There are {0} form instances", Application.OpenForms.Count))
  End Sub

There are many possible fixes for your problem. You could marshal the call to the UI thread with Control.Begin/Invoke(). Although that requires access to a form or control instance, a bit of a chicken-and-egg problem. Best thing to do is to simply pass the form instance to the helper's class constructor:

Class Helper
  Private mForm As Form1
  Public Sub New(ByVal frm As Form1)
    mForm = frm
  End Sub
End Class

Now you have the instance you need.

Hans Passant