How do I detect a form being opened already

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

In VB 5 I could have a form named frmTest and open it with
frmTest.Show

Now in VB.net I have to
Dim frm as New frmTest
frm.show

The problem is I only want one instance of frmTest open, not a new one each
time.
Is there a way to prevent this, or test for the form being open already?

Thanks
Rich
 
Hi RichG,

I don't know if this is the preferable solution, but it works...

In my example, Form1 opens Form2, but Form2 can only have one instance....

FORM1....

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim frm As Form2 = Form2.GetInstance
frm.Show()
frm.BringToFront()
End Sub

FORM2....

Public Class Form2

Private Shared _instance As Form2

Public Shared Function GetInstance() As Form2
If _instance Is Nothing Then
_instance = New Form2
End If
Return _instance
End Function

Private Sub Form2_FormClosed(ByVal sender As Object, ByVal e As
System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
_instance = Nothing
End Sub

End Class


Look out for wrappings.

Hope it was what you're looking for. :o)

Kind regards,
M oj o
 
Hello, Rich,

I'm not aware of anything that replaces the VB "Forms" collection.
There must be something referencing the form while it is being shown,
because it continues to exist after the variable "frm" is no longer in
scope, but I haven't been able to figure out how to get this reference.

Just in case nobody else can tell us what replaces the old VB "Forms",
here are some of my thoughts:

I had a need like yours with an MDI application that allowed several
types of forms to be open simultaneously, but only one of each type. I
just iterated through the MDI forms MDIChildren collection and compared
the type of each child form with that of the form I was about to open.
If I found it, I activated it. If I didn't I opened it.

I suppose that if all of your forms (except one at the top of the
hierarchy) have Owner forms you could iterate (recursively from the top
level form) through the OwnedForms doing something similar.

Alternatively, you could declare a shared boolean variable and test it
in the form constructor. If the flag is set, throw an error. If it is
not, set it and continue. Then you could catch the error in the code
that opens the form. I.e. in the form have something like:

Public Class Form1
Inherits System.Windows.Forms.Form

Private Shared m_Exists As Boolean = False

Public Sub New()
MyBase.New()

If (m_Exists) Then
Throw New FormAlreadyOpenException("Form " & _
Me.Name & " already exists!")
End If
m_Exists = True

'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides _
Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
m_Exists = False
End If
MyBase.Dispose(disposing)
End Sub
. . .
. . .

and for opening it:

Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Try
Dim frmNew As New Form1
frmNew.Text = "Single Instance Form "
frmNew.Show()
frmNew = Nothing

Catch ex As FormAlreadyOpenException
MsgBox(ex.Message)

End Try
End Sub

Alternatively you could put the test/set into the Form Load event and
clear it in the Form close event. That would allow multiple instances
of the form to be created/exist, but should prevent more than one
instance at a time from being shown.

Or, as still another alternative, if you could derive all the "show
once" forms from a common base form, then you could include code in that
base to add the form to a global "FormsAlreadyOpen" collection and use
that like the old VB Forms collection.

Or, wait for someone wiser to tell us where the Forms collection has
gone... ;-)

Cheers,
Randy
 
AFAIK = As Far As I Know. (easy to test in this case, however writing it, I
did not, because it was not really important for the question.).
 
MOJO's response is a classic singleton pattern which is a way of ensuring
only one instance of the class (in this case, the form) is used. The one
change to his sample I would make would be to change the form's constructor
private, thereby requiring consumers to use the GetInstance method.

Jim
 
Thanks guys for the suggestions. The painters came in today so I'm in a low
productivity mode for the day.
I hope to get back to this this evening or tomorrow.
Thanks again.
 
Back
Top