0

I have a program that we use to run different reports. Based on the menu option chosen, I open the same form that lists the reports based on the menu option. (There are also different options and functionalities in the program, not just one form).

When clicking a menu option, I have the following bit of code

Private Sub ReportsToolStripMenuItem1_Click(sender As Object, e As     EventArgs) Handles ReportsToolStripMenuItem1.Click
    FormLocation = "F_Legal"
    FormName = "Legal"
    PrepareForm(F_Select_Report)
End Sub 'ReportsToolStripMenuItem1_Click

Where F_Select_Report the form is that is opened.

Private Sub PrepareForm(formName As Form)
    Cursor = Cursors.WaitCursor
    For Each Form In Me.MdiChildren
        Form.Close()
    Next

    formName.MdiParent = Me
    formName.Height = Me.Height
    formName.Width = Me.Width
    formName.Show()
    Cursor = Cursors.Arrow
End Sub 'PrepareForm

This bit is called, closing all other opened forms, and then open the form that is called.

This works fine on the first time I try and open a form, but on the second try, I get an error message saying

Cannot access a disposed object.

And then on the third try, it opens the form again. How would I fix this up?

Thanks a lot

Gerben
  • 117
  • 1
  • 2
  • 10
  • Are you sure that you were going to use `Me.MdiChildren` and not `formName.MdiChildren`? A form that is not opened yet wouldn't have any MDI children AFAIK. – Visual Vincent Jun 07 '16 at 14:46
  • Is _F_Select_Report_ an instance of a form or is it the Class name of the form? – Steve Jun 07 '16 at 14:46
  • The [documentation](https://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx) say then when you close a form it gets disposed. That's why it doesn't work the second time. You should keep the form open or create a new instance. – the_lotus Jun 07 '16 at 14:51
  • @VisualVincent My main form has a MenuStrip, from here they select a menu option. So I want to close all forms but the main form, as all forms have the same MdiParent. – Gerben Jun 07 '16 at 15:34
  • @Steve F_Select_Report is a form – Gerben Jun 07 '16 at 15:34
  • If it is a MDI child of your MDI main form then your loop destroys it (dispose) so you cannot use it until you create a new instance of it – Steve Jun 07 '16 at 15:36

2 Answers2

0

Form.Close implicitly calls Form.Dispose So if the formName is an MdiChild it gets disposed in the For Each loop. Then, on the next line your code attempts to assign to its MdiParent property and there the error occurs. So you need to skip it when closing MDI children like this:

For Each Form In Me.MdiChildren
    If Not Form Is formName Then Form.Close
Next

Given your code I think it is better to close the children before showing the F_Select_Report form. I.e. move the For Each loop as is to the top of the ReportsToolStripMenuItem1_Click handler.

Bozhidar Stoyneff
  • 3,576
  • 1
  • 18
  • 28
0

Not sure if it is the best/nicest solution, but found a solution to this. Instead of 1 Sub that does both closes all open forms, and then opens the new one, I split it out over 2 Subs.

Close all open ones

Private Sub CloseAllForms()
    For Each Form In Me.MdiChildren
        Form.Close()
    Next
End Sub 'CloseAllForms

And then open the new form

Private Sub PrepareForm(formName As Form)
    Cursor = Cursors.WaitCursor
    Try
        formName.MdiParent = Me
        formName.Height = Me.Height
        formName.Width = Me.Width
        formName.Show()
    Catch ex As Exception
        MessageBox.Show("Error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
    Cursor = Cursors.Arrow
End Sub 'PrepareForm

Now it works as needed.

Gerben
  • 117
  • 1
  • 2
  • 10