Results 1 to 11 of 11

Thread: [RESOLVED] What is the best way to close all open child forms

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    Resolved [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.

    Name:  Screenshot_1.jpg
Views: 7200
Size:  28.8 KB

    vb.net Code:
    1. Public Sub ShowForm(ByVal Frm As Form)
    2.         For Each frmClose As Form In MainForm.MdiChildren
    3.             frmClose.Close()
    4.             frmClose.Dispose()
    5.         Next
    6.         With Frm
    7.             .MdiParent = MainForm
    8.             .Show()
    9.             .WindowState = FormWindowState.Maximized
    10.         End With
    11.     End Sub

    vb.net Code:
    1. Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
    2.         ShowForm(FrmPermintaan)
    3.     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.
    Name:  Screenshot_4.jpg
Views: 6560
Size:  30.7 KB

    Please help
    Attached Images Attached Images   

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    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:
    1. For Each frmClose As Form In MainForm.MdiChildren.ToArray()
    2.     frmClose.Close()
    3. Next
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    Re: What is the best way to close all open child forms

    Quote Originally Posted by jmcilhinney View Post
    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:
    1. For Each frmClose As Form In MainForm.MdiChildren.ToArray()
    2.     frmClose.Close()
    3. 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

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    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:
    1. Dim f1 As New Form1
    2.  
    3. f1.Show()
    you can do this:
    vb.net Code:
    1. Form1.Show()
    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    Re: What is the best way to close all open child forms

    Quote Originally Posted by jmcilhinney View Post
    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:
    1. Dim f1 As New Form1
    2.  
    3. f1.Show()
    you can do this:
    vb.net Code:
    1. Form1.Show()
    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?
    Name:  Screenshot_1.jpg
Views: 6136
Size:  15.9 KB

  6. #6

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    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:
    1. Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
    2.         checkActive = Active
    3.         Active = "FrmPR"
    4.         ShowForm(FrmPR)
    5.     End Sub

    vb.net Code:
    1. Public Sub ShowForm(ByVal Frm As Form)
    2.         If checkActive <> Active Then
    3.             For Each frmClose As Form In MainFrm.MdiChildren.ToArray()
    4.                 frmClose.Close()
    5.             Next
    6.             With Frm
    7.                 .MdiParent = MainFrm
    8.                 .Show()
    9.                 .WindowState = FormWindowState.Maximized
    10.             End With
    11.         End If
    12.     End Sub
    Last edited by kevintaw; Apr 19th, 2017 at 09:37 PM.

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: What is the best way to close all open child forms

    Quote Originally Posted by kevintaw View Post
    Oh, sorry but where can I create the new instance?
    Name:  Screenshot_1.jpg
Views: 6136
Size:  15.9 KB
    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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: What is the best way to close all open child forms

    Quote Originally Posted by kevintaw View Post
    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:
    1. Private Sub TsbTPR_Click(sender As Object, e As EventArgs) Handles TsbTPR.Click
    2.         checkActive = Active
    3.         Active = "FrmPR"
    4.         ShowForm(FrmPR)
    5.     End Sub

    vb.net Code:
    1. Public Sub ShowForm(ByVal Frm As Form)
    2.         If checkActive <> Active Then
    3.             For Each frmClose As Form In MainFrm.MdiChildren.ToArray()
    4.                 frmClose.Close()
    5.             Next
    6.             With Frm
    7.                 .MdiParent = MainFrm
    8.                 .Show()
    9.                 .WindowState = FormWindowState.Maximized
    10.             End With
    11.         End If
    12.     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:
    1. If FrmPr.IsDisposed Then
    2.     FrmPr = New Form1
    3. End If
    4.  
    5. 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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    Re: What is the best way to close all open child forms

    Quote Originally Posted by jmcilhinney View Post
    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:
    1. If FrmPr.IsDisposed Then
    2.     FrmPr = New Form1
    3. End If
    4.  
    5. 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"?

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    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?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11

    Thread Starter
    New Member
    Join Date
    Apr 2017
    Posts
    11

    Re: What is the best way to close all open child forms

    Quote Originally Posted by jmcilhinney View Post
    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

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width