4 Attachment(s)
[RESOLVED] What is the best way to close all open child forms
Hello, I need some help.
How (what is the best way) to close all open child forms in VB.NET?
Here is my code and screenshot of the program.
Attachment 146829
vb.net Code:
Public Sub ShowForm(ByVal Frm As Form)
For Each frmClose As Form In MainForm.MdiChildren
frmClose.Close()
frmClose.Dispose()
Next
With Frm
.MdiParent = MainForm
.Show()
.WindowState = FormWindowState.Maximized
End With
End Sub
vb.net Code:
Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
ShowForm(FrmPermintaan)
End Sub
When I click another form, it seems like the "form closing" process is not really neat and see some blink.
Video: https://www.screencast.com/t/M8NYwOVDH
Also, when I use the above code and I click the same form, it gives this error:
Cannot access a disposed object.
Attachment 146837
Please help
Re: What is the best way to close all open child forms
There's no point to calling Close and Dispose. If a form is displayed by calling Show, as must be the case for an MDI child, then closing the form also disposes it. It's only when displayed by calling ShowDialog that a form requires explicit disposing after being closed.
Also, you should not be using a For Each loop like that. Never enumerate a collection with a For Each loop and then modify that collection inside the loop. Closing an MDI child makes it no longer an MDI child, so you're modifying the MdiChildren collection. One solution is to create an array from the collection and then enumerate that. The array won't change even if you change the collection.
vb.net Code:
For Each frmClose As Form In MainForm.MdiChildren.ToArray()
frmClose.Close()
Next
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
jmcilhinney
There's no point to calling Close and Dispose. If a form is displayed by calling Show, as must be the case for an MDI child, then closing the form also disposes it. It's only when displayed by calling ShowDialog that a form requires explicit disposing after being closed.
Also, you should not be using a For Each loop like that. Never enumerate a collection with a For Each loop and then modify that collection inside the loop. Closing an MDI child makes it no longer an MDI child, so you're modifying the MdiChildren collection. One solution is to create an array from the collection and then enumerate that. The array won't change even if you change the collection.
vb.net Code:
For Each frmClose As Form In MainForm.MdiChildren.ToArray()
frmClose.Close()
Next
Ah I understand now, but when I click Form A, and then I click again the same form (Form A), it gives me this error:
Cannot access a disposed object.
I have recorded it here:
https://www.screencast.com/t/aZ5WgZvCXny
Thank you
Re: What is the best way to close all open child forms
You must be calling Show on the same instance as you previously called Close on. If you call Show on a form and then call Close, that form is disposed. You can still access it to get data from it but you cannot display it again. If you want to display a form of that type to the user again then you must create a new instance.
I'm not a big fan of default instances in general but this is one case where using them might help. If you never intend more than one instance of a type of form to be displayed at a time then you can use the default instance and that will automatically manage creation for you. Instead of doing this:
vb.net Code:
Dim f1 As New Form1
f1.Show()
you can do this:
That will display the default instance. The system will automatically handle creating a new instance if there isn't one already or the one that exists has been disposed.
1 Attachment(s)
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
jmcilhinney
You must be calling Show on the same instance as you previously called Close on. If you call Show on a form and then call Close, that form is disposed. You can still access it to get data from it but you cannot display it again. If you want to display a form of that type to the user again then you must create a new instance.
I'm not a big fan of default instances in general but this is one case where using them might help. If you never intend more than one instance of a type of form to be displayed at a time then you can use the default instance and that will automatically manage creation for you. Instead of doing this:
vb.net Code:
Dim f1 As New Form1
f1.Show()
you can do this:
That will display the default instance. The system will automatically handle creating a new instance if there isn't one already or the one that exists has been disposed.
Oh, sorry but where can I create the new instance?
Attachment 146847
Re: What is the best way to close all open child forms
I try playing with string, it works but I don't think it's a good way, need some advice. So my concept is checking the string whether it is opening the same form, if yes then no need to close & open itself
vb.net Code:
Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
checkActive = Active
Active = "FrmPR"
ShowForm(FrmPR)
End Sub
vb.net Code:
Public Sub ShowForm(ByVal Frm As Form)
If checkActive <> Active Then
For Each frmClose As Form In MainFrm.MdiChildren.ToArray()
frmClose.Close()
Next
With Frm
.MdiParent = MainFrm
.Show()
.WindowState = FormWindowState.Maximized
End With
End If
End Sub
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
kevintaw
You seem to be unfamiliar with the concept of an example. I used Form1 as an example of what a form type might be named. You need to use the name of YOUR form type, not just copy and paste what's in my example. The thing is, if you're going to be passing forms of different types to that method that you can't do the creation part inside that method. You need to do it before you call that method. You need to check whether your current instance is disposed and create a new one if it is, then pass the undisposed instance to your method.
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
kevintaw
I try playing with string, it works but I don't think it's a good way, need some advice. So my concept is checking the string whether it is opening the same form, if yes then no need to close & open itself
vb.net Code:
Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
checkActive = Active
Active = "FrmPR"
ShowForm(FrmPR)
End Sub
vb.net Code:
Public Sub ShowForm(ByVal Frm As Form)
If checkActive <> Active Then
For Each frmClose As Form In MainFrm.MdiChildren.ToArray()
frmClose.Close()
Next
With Frm
.MdiParent = MainFrm
.Show()
.WindowState = FormWindowState.Maximized
End With
End If
End Sub
There's no need for any String. The Form class has an IsDisposed property that you can use to determine whether a form is disposed. Here's an EXAMPLE:
vb.net Code:
If FrmPr.IsDisposed Then
FrmPr = New Form1
End If
ShowForm(FrmPr)
Again, I don't know what your form type is so I have used Form1 as an example. You need to use your form type and if you have similar code for multiple form types then you need to do this once for each form type.
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
jmcilhinney
There's no need for any String. The Form class has an IsDisposed property that you can use to determine whether a form is disposed. Here's an EXAMPLE:
vb.net Code:
If FrmPr.IsDisposed Then
FrmPr = New Form1
End If
ShowForm(FrmPr)
Again, I don't know what your form type is so I have used Form1 as an example. You need to use your form type and if you have similar code for multiple form types then you need to do this once for each form type.
Thank you for your answer, I am sorry but where can I find the "form type"?
Re: What is the best way to close all open child forms
You must have created an object and assigned it to that variable at some point in your code already. What type of object did you create then? That's the same type of object that you need to create now. Why would it be any different?
Re: What is the best way to close all open child forms
Quote:
Originally Posted by
jmcilhinney
You must have created an object and assigned it to that variable at some point in your code already. What type of object did you create then? That's the same type of object that you need to create now. Why would it be any different?
Ah ok thank you mate :)