Determining when a form is really closed

I have an MDI for with child forms created as needed.
I have them set up to auto-arrange (me.LayoutMdi) so I can see all of them at the same time.  If I add a form, they autoarrange just fine.

The problem is that when I close a form, they don't autoarrange.
I intercepted the Closed event but apparently the form is not closed yet.

How do I know when a form is really closed?

(If this doesn't have a direct answer, I'll bump up the points and I'll take the one that has the most elegant and/or simple solution to rearranging the remaining forms after one closes.)

To confirm that a form is not closed when the closed event occurs, try the code below.  If a form is really closed then it should have no name (or a default name) when it is closed.

    Private WithEvents frm As Form1

    Private Sub frm_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles frm.Closed
    End Sub

    Private Sub lblCurrentLine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblCurrentLine.Click
        frm = New Form1
        frm.Name = "anything"
    End Sub
LVL 22
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

If Not IsNothing(frm) Then ''form is not closed

Else '' form is closed

End IF
rspahitzAuthor Commented:
Sorry...I need an event that tells me when it's closed...
(It's: how do I know WHEN a form is closed, not IF it is "closed")
in every form is a "fromclosing" and a "formClosed" can use that to capture the event and put whatever code you need to...pass something back to the mdiparent or a msgbox or whatever
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

rspahitzAuthor Commented:
The Closing and Closed events occur BEFORE the form closes.  See my sample code in the question.
well... the closest you can get is Closed and since you find out that the form is not actually closed when it's Closed ;) you may want to use some kind of a trick...

like starting a timer in your Closed, which set it to 100 ms, in the timer check for the name of a form and if it's closed, launch whatever method you want to notify your that the form IS closed, and stop the timer.

In theory, it should be on the first call (the first 100 ms).

good luck,

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Bob LearnedCommented:
I believe that the one way would to monitor when the Finalize method is called (when the form is disposed), but that requires that the form is disposed:

Protected Overrides Sub Finalize()
End Sub

rspahitzAuthor Commented:
The finalize seemed like it could lead to something...I intercepted several events, like Dispose, etc, but they hadn't gotten rid of the form yet.
And for some reason, the Finalize never gets fired!

I was hoping to avoid the timer, but the idea of turning it on until the form is blank seems good enough.  I really wish that the MDI form would notify you if one of its children closes.

Anyway, here's bits of the code I used (for future reference, with the names changed to protect the innocent):
Child form:

    Private Sub frmChild_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        Dim frm As frmMDIParent = Nothing

        If TypeOf (Me.Parent) Is frmMDIParent Then
            frm = Parent
            If TypeOf (Me.Parent.Parent) Is frmMDIParent Then
                frm = Parent.Parent
            End If
        End If

        If Not IsNothing(frm) Then
            With frm
                frm.ChildFormBeingClosed = Me.Text
                frm.tmrWaitingForFormClose.Enabled = True
            End With
        End If
    End Sub

Parent form:

    Private mptrChildForm As IntPtr
    Public WriteOnly Property ChildFormBeingClosed() As IntPtr
        Set(ByVal Value As IntPtr)
            mptrChildForm = Value
        End Set
    End Property

    Private miTimerCntr As Integer = 0
    Private Sub tmrWaitingForFormClose_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles tmrWaitingForFormClose.Tick
        If Not ChildFormFound(mptrChildForm) Then
            Me.tmrWaitingForFormClose.Enabled = False
        End If
    End Sub

    Private Function ChildFormFound(ByVal FormName As IntPtr) As Boolean
        Dim frm As Form
        Dim bChildfound As Boolean = False

        For Each frm In Me.MdiChildren
            If frm.Handle.ToString Is FormName.ToString Then
                bChildfound = True
                Exit For
            End If
        Next frm

        Return bChildfound
    End Function
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.