Multiple Instances of a Form

G

Guest

I have FormA that opens FormB on request. Before opening FormB, I'd like to see if it is already open to prevent multiple instances. I'm not sure if I'm on the right track... but I have created a form level variable

dim frmB as frmMyPrintFor

In the button's click event..

If Not frmB Is Nothing The
frmB.BringToFront(
Els
frmB = New frmMyPrintFor
frmB.MdiParent = Me.MdiParen
frmB.Show(
End I

The problems is... when the user opens frmB once, then presses 'Close' (Me.Close) or the X close button, frmB no longer evaluates to 'nothing' and the form is not shown with BringToFront(). I understand that the resources are released after me.close, but how can I make the above code work? I thought I saw an example where someone checked if frmB is Disposing... but I can't find the syntax for that.

I know that I could 'hide' the form instead of actually closing it, but since the form could be called from multiple sources, I'd like not to have the overhead of keeping track of it

Any ideas

Thanks
Denise
 
A

Andy Gaskell

Something like this should work:

If frmB Is Nothing Or frmB.IsDisposed Then
frmB = New frmMyPrintForm
frmB.MdiParent = Me.MdiParent
frmB.Show()
Else
frmB.BringToFront()
End If

Denise said:
I have FormA that opens FormB on request. Before opening FormB, I'd like
to see if it is already open to prevent multiple instances. I'm not sure if
I'm on the right track... but I have created a form level variable:
dim frmB as frmMyPrintForm

In the button's click event...

If Not frmB Is Nothing Then
frmB.BringToFront()
Else
frmB = New frmMyPrintForm
frmB.MdiParent = Me.MdiParent
frmB.Show()
End If

The problems is... when the user opens frmB once, then presses 'Close'
(Me.Close) or the X close button, frmB no longer evaluates to 'nothing' and
the form is not shown with BringToFront(). I understand that the resources
are released after me.close, but how can I make the above code work? I
thought I saw an example where someone checked if frmB is Disposing... but I
can't find the syntax for that.
I know that I could 'hide' the form instead of actually closing it, but
since the form could be called from multiple sources, I'd like not to have
the overhead of keeping track of it.
 
M

Muhammad Mudasar Ansari

Hi
I have solved the problem in this way... There might be a better way to
solve this problem

Private Sub mnuSupplier_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuSupplier.Click
If isFormLoaded("Supplier Profile") Then
frmSup.Show()
frmSup.BringToFront()
Exit Sub
End If
frmSup = New frmSupplier()
frmSup.MdiParent = Me
frmSup.Text = "Supplier Profile"
frmSup.Show()
frmSup.StartPosition = FormStartPosition.CenterParent
frmSup.BringToFront()
End Sub

Private Function isFormLoaded(ByVal frmText As String) As Boolean
Dim f As Form
For Each f In Me.MdiChildren
If f.Text = frmText Then Return True
Next

End Function

Ansari


Denise said:
I have FormA that opens FormB on request. Before opening FormB, I'd like
to see if it is already open to prevent multiple instances. I'm not sure if
I'm on the right track... but I have created a form level variable:
dim frmB as frmMyPrintForm

In the button's click event...

If Not frmB Is Nothing Then
frmB.BringToFront()
Else
frmB = New frmMyPrintForm
frmB.MdiParent = Me.MdiParent
frmB.Show()
End If

The problems is... when the user opens frmB once, then presses 'Close'
(Me.Close) or the X close button, frmB no longer evaluates to 'nothing' and
the form is not shown with BringToFront(). I understand that the resources
are released after me.close, but how can I make the above code work? I
thought I saw an example where someone checked if frmB is Disposing... but I
can't find the syntax for that.
I know that I could 'hide' the form instead of actually closing it, but
since the form could be called from multiple sources, I'd like not to have
the overhead of keeping track of it.
 
G

Guest

Hello Denise
Yours is a real simple problem. The key is to understand that a form-level variable is not garbage-collected and disposed of until the form itself is disposed. Successive garbage collection will eventually promote the reference to the form-level varibale to the 2nd generation, members of which has the longest lifetime lease

In your problem, your varibale that references FormB is declared at the form-level (by the way declare it with the private modifier and not the Dim, use dim only with methods or local code blocks). Hence even if Form B is opened and then closed, the reference to the memory provided to FormB by the CLR is not recovered, and hence frmB will never transcend to Nothing
However, when it is disposed, the state of the object is lost and the space allocated in memory is reclaimed. Hence calling any property on the object without re-instantiating it will result in an exception. And this is what we can look for to prevent multiple instances

Tr
frmB.Visible = True 'will affect the property of the existing instanc
Catch e As Exception 'exception is thrown if the object had been dispose
frmB = New frmMyPrintForm() 're-instantiat
frmB.Show() 'and sho
End Tr

Cheers!!
 
G

Guest

Thanks to everyone for your reply - that was very helpful. I tried Any's solution, but I kept getting an error the very first time on 'frmB.IsDisposing' saying 'Object Reference not set to an instance of an object'

I tried this variation (adding OrElse in place of Or to avoid evaluating both conditions) and it seemed to work
If frmB Is Nothing OrElse frmB.IsDisposed The
frmB = New frmMyPrintFor
frmB.MdiParent = Me.MdiParen
frmB.Show(
Els
frmB.BringToFront(
End I

Thanks again
Denise
 
A

Andy Gaskell

Doh! Sorry about that - I thought in VB.NET the Or operator did
short-circuiting.

Denise said:
Thanks to everyone for your reply - that was very helpful. I tried Any's
solution, but I kept getting an error the very first time on
'frmB.IsDisposing' saying 'Object Reference not set to an instance of an
object'.
I tried this variation (adding OrElse in place of Or to avoid evaluating
both conditions) and it seemed to work:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top