How do we close a modeless form in vb.net ?

dominico

Well-known member
Joined
Mar 9, 2005
Messages
57
Programming Experience
3-5
I need help with closing a modeless form. When I use form.close(), nothing happens. I can open it but cannot close it or hide it or focus it.

I also need to know how to check if it is under "Show" state or not.

Please advise me on how to do it.


Below are my code:

PrivateSub ShowForm(ByVal SomeForm As Form, ByVal doThis AsString)
SomeForm.WindowState = FormWindowState.Normal

SelectCase doThis

Case "Show"

SomeForm.Show()

SomeForm.Controls.Item(0).Text = sAll

Case "Off"

SomeForm.Close() ' This line has no affect on my MODELESS FORM

EndSelect

EndSub


Thank you everyone.

dominico
 
Last edited:
JuggaloBrotha said:
have you tested the variables to see if the Case "Off" line is ever actually being executed?


Yes, I walked through everyline with vb debug using breakpoint.


Thanks.
 
Are you sure that the instance you are passing in the SomeForm argument is the instance you think it is? I used this code to open, close and actiavate a modeless dialogue repeatedly with no issue:
VB.NET:
	Private modelessDialogue As Form2

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		If Me.modelessDialogue Is Nothing OrElse Me.modelessDialogue.IsDisposed Then
			Me.modelessDialogue = New Form2
			Me.AddOwnedForm(Me.modelessDialogue)
			Me.modelessDialogue.Show()
		Else
			Me.modelessDialogue.Activate()
		End If
	End Sub

	Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
		If Not Me.modelessDialogue Is Nothing AndAlso Not Me.modelessDialogue.IsDisposed Then
			Me.modelessDialogue.Close()
		End If
	End Sub
 
jmcilhinney said:
Are you sure that the instance you are passing in the SomeForm argument is the instance you think it is? I used this code to open, close and actiavate a modeless dialogue repeatedly with no issue:
VB.NET:
	Private modelessDialogue As Form2
 
	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		If Me.modelessDialogue Is Nothing OrElse Me.modelessDialogue.IsDisposed Then
			Me.modelessDialogue = New Form2
			Me.AddOwnedForm(Me.modelessDialogue)
			Me.modelessDialogue.Show()
		Else
			Me.modelessDialogue.Activate()
		End If
	End Sub
 
	Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
		If Not Me.modelessDialogue Is Nothing AndAlso Not Me.modelessDialogue.IsDisposed Then
			Me.modelessDialogue.Close()
		End If
	End Sub


Hi jmcilhinney,

Thanks for the reply. As for my case, it doesn't work because I have two seperate forms. I am trying to access form2 within form1. When I try to use your example above, when I type "me.form2", my form1(me) did not recognize and list the name of my form2. If your could, create two different window forms and see if you could replicate my case please.

dominico
 
You'll notice that in my example the instance of Form2 is assigned to a class-level variable so that you can refer to that form by that variable anywhere. If you assign it to a local variable when you create it then you can't refer to that form by that variable outside the method it was created in. If your form is indeed a modeless dialogue, i.e. an owned form, you can still access it via the OwnedForms property of form1, which is an array of Forms that were added using AddOwnedForm.
 
jmcilhinney said:
You'll notice that in my example the instance of Form2 is assigned to a class-level variable so that you can refer to that form by that variable anywhere. If you assign it to a local variable when you create it then you can't refer to that form by that variable outside the method it was created in. If your form is indeed a modeless dialogue, i.e. an owned form, you can still access it via the OwnedForms property of form1, which is an array of Forms that were added using AddOwnedForm.


My apology. I wasn't using the AddOwnedForm feature. I added it to my code and it works.

Thank you jmcilhinney.

dominico
 
I mentioned the AddOwnedForm method because you said you were using a modeless dialogue. A true modeless dialogue behaves like the Find and Replace window in VS, where it is always in front of the owner but you can still access the owner, while a modal dialogue denies access to the opener altogether. Only use AddOwnedForm if that is the behaviour that you want. If you just want a window, as opposed to a true dialogue, you can still maintain a reference to it in the form that opened it in a class-level variable, as I said.
 
jmcilhinney said:
I mentioned the AddOwnedForm method because you said you were using a modeless dialogue. A true modeless dialogue behaves like the Find and Replace window in VS, where it is always in front of the owner but you can still access the owner, while a modal dialogue denies access to the opener altogether. Only use AddOwnedForm if that is the behaviour that you want. If you just want a window, as opposed to a true dialogue, you can still maintain a reference to it in the form that opened it in a class-level variable, as I said.

Yes, you are correct. I overlooked. I thought I could do it the same way I did it with VB6. VB.Net changed a lot.

Thanks again my good friend.

dominico
 
jmcilhinney said:
With regards to VB6, my advice is to assume that everything is different in VB.NET and consider it a bonus if something actually does turn out to be the same. :)


So true. I have to stop using the old ways. :p

jmcilhinney, quick question. I use your code above. The problem is that if I close the modeless form(by clicking on the "X" at the top right hand corner of the form," and then click on the button on my main form to start it up again.. VB complains when it runs into the method "Show" below. I guess it is because the modeless form is still in the buffer. How do we check to see if it is there so that we can do "modelessform2.Activate()" instead ?

If Not DisplayScript Is Nothing OrElse DisplayScript.IsDisposed Then

DisplayScript.Show()

End If

 
You should use my code as I wrote it and just change the name of the variable. The code that you have provided will call Show on the form if it has been opened and then closed, i.e. disposed. You would have to put a "Not" in front of "DisplayScript.IsDisposed" so as not to try to Show a Disposed form.
 
jmcilhinney said:
You should use my code as I wrote it and just change the name of the variable. The code that you have provided will call Show on the form if it has been opened and then closed, i.e. disposed. You would have to put a "Not" in front of "DisplayScript.IsDisposed" so as not to try to Show a Disposed form.


hi jmcilhinney,

Below is my code. I did as told but the activate didn't bring back the modeless form. I tested it with vb debug.

Sub DisplayMe(ByVal doThis As String)

DisplayScript.WindowState = FormWindowState.Normal

Select Case doThis

Case "showit"

If Not DisplayScript Is Nothing AndAlso Not DisplayScript.IsDisposed Then

DisplayScript.Show()

Else

DisplayScript.Activate()

End If

Case "hideit"

DisplayScript.Hide()

End Select

DisplayScript.lbDisplay.Text = sAll

End Sub

 
I'm afraid that you haven't done as I suggested.

My code, with your variable name, would be:
VB.NET:
If Me.[size=2]DisplayScript[/size] Is Nothing OrElse Me.[size=2]DisplayScript[/size].IsDisposed Then
	'Form has not been created or has been disposed (i.e. closed).
	Me.[size=2]DisplayScript[/size] = New <applicable type>
	Me.AddOwnedForm(Me.[size=2]DisplayScript[/size])
	Me.[size=2]DisplayScript[/size].Show()
Else
	'Form is currently displayed (i.e. called Show but not Close)
	Me.[size=2]DisplayScript[/size].Activate()
End If
Notice I don't use "Not" anywhere.

You code is:
VB.NET:
[size=2][color=#0000ff]If[/color][/size][size=2][color=#0000ff] Not[/color][/size][size=2] DisplayScript [/size][size=2][color=#0000ff]Is[/color][/size][size=2][color=#0000ff] Nothing[/color][/size][size=2][color=#0000ff] AndAlso [/color][/size][size=2][color=#0000ff]Not[/color][/size][size=2] DisplayScript.IsDisposed [/size][size=2][color=#0000ff]Then
[/color][/size][size=2]	'Form is currently displayed.
	DisplayScript.Show()
[/size][size=2][color=#0000ff]Else
[/color][/size][size=2]	'Form has not been created or has been disposed.
	DisplayScript.Activate()
[/size][size=2][color=#0000ff]End[/color][/size][size=2][color=#0000ff]If[/color][/size]
You have used "Not" and "AndAlso, which means that where my condition is True your's is False, and where my condition is False your's is True. This means you would have switch the calls to Show and Activate. Also, if the form doesn't exist or is disposed, you need to create a new instance. My code does that but your's does not. Also, calling Show on a form that is already displayed has the same effect as setting the Visible property to True. It does not bring the form to the front of the Z-order and give it focus, which Activate does.
 
jmcilhinney said:
I'm afraid that you haven't done as I suggested.

My code, with your variable name, would be:
VB.NET:
If Me.[size=2]DisplayScript[/size] Is Nothing OrElse Me.[size=2]DisplayScript[/size].IsDisposed Then
	'Form has not been created or has been disposed (i.e. closed).
	Me.[size=2]DisplayScript[/size] = New <applicable type>
	Me.AddOwnedForm(Me.[size=2]DisplayScript[/size])
	Me.[size=2]DisplayScript[/size].Show()
Else
	'Form is currently displayed (i.e. called Show but not Close)
	Me.[size=2]DisplayScript[/size].Activate()
End If
Notice I don't use "Not" anywhere.

You code is:
VB.NET:
[size=2][color=#0000ff]If[/color][/size][size=2][color=#0000ff] Not[/color][/size][size=2] DisplayScript [/size][size=2][color=#0000ff]Is[/color][/size][size=2][color=#0000ff] Nothing[/color][/size][size=2][color=#0000ff] AndAlso [/color][/size][size=2][color=#0000ff]Not[/color][/size][size=2] DisplayScript.IsDisposed [/size][size=2][color=#0000ff]Then
[/color][/size][size=2]	'Form is currently displayed.
	DisplayScript.Show()
[/size][size=2][color=#0000ff]Else
[/color][/size][size=2]	'Form has not been created or has been disposed.
	DisplayScript.Activate()
[/size][size=2][color=#0000ff]End[/color][/size][size=2][color=#0000ff]If[/color][/size]
You have used "Not" and "AndAlso, which means that where my condition is True your's is False, and where my condition is False your's is True. This means you would have switch the calls to Show and Activate. Also, if the form doesn't exist or is disposed, you need to create a new instance. My code does that but your's does not. Also, calling Show on a form that is already displayed has the same effect as setting the Visible property to True. It does not bring the form to the front of the Z-order and give it focus, which Activate does.

Sorry bro,

I tried it again with the exact same code this time and I didn't get the second form to display at all now. Please advise.

Here is my code using yours:

Sub DisplayMe(ByVal doThis As String)

Dim DisplayScript As New frmDisplay

DisplayScript.WindowState = FormWindowState.Normal

If DisplayScript Is Nothing OrElse DisplayScript.IsDisposed Then

'Form has not been created or has been disposed (i.e. closed).

DisplayScript = New frmDisplay

AddOwnedForm(DisplayScript)

DisplayScript.Show()

Else

'For is currently displayed (i.e. called Show but no Close)

DisplayScript.Activate()

End If

'Select Case doThis

' Case "showit"

' If Not DisplayScript Is Nothing AndAlso Not DisplayScript.IsDisposed Then

' DisplayScript.Show()

' Else

' DisplayScript.Activate()

' End If

' Case "hideit"

' DisplayScript.Hide()

'End Select

DisplayScript.lbDisplay.Text = sAll

End Sub

 
Back
Top