MDI child windows

Posted on 2005-04-18
Last Modified: 2012-06-27
When closing the last child window in the application, I need to disable menu items like Save and Print. I have all the logic written to do so, but when the last child window is closed from its own 'X' button instead of the parent window's Close menu item, the parent still thinks there's one form open for some reason.

After closing the last child window using its 'X' button, the menu items are still enabled. But if I click the Close or Close All menu buttons on the parent, then the menu items are disabled correctly.

I have a sub in the parent called UpdateControlState that uses MdiChildren.Length to handle menu items. I tried to use the code below but it never gets called:

    Public Sub ClosedHandler(ByVal Sender As [Object], ByVal e As EventArgs) Handles MyBase.Closed

        mainWin = Me.MdiParent
        'If there are no child windows, then disable menu and toolbar items.
        If mainWin.MdiChildren.Length = 0 Then
        End If

    End Sub

How can I force an update of the parent window's mdiChildren collection? Should I?


Question by:k3n51mm
    LVL 34

    Expert Comment

    by:Brian Crowe
    If you do a trace or step through your code I believe you will find that the MDIClient is your mysterious window.
    LVL 32

    Accepted Solution

    Since your MDIMain form creates the child forms, it should also maintain a list of them.  You can add an event handler to your MDIMain form so you will be notified when new child forms are added and removed.  Your MDIMain form can also maintain a collection of the child forms to get the count.

    In your MDIMain form code:

        'Create a collection to hold the child forms:
        Private colChildForms As New Collection

    'Now add two events to receive notification when new child forms are added or removed:

        Private Sub MDIChild_Add(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim handle As String = DirectCast(sender, Form).Handle.ToString
            'Add the form to our collection
            colChildForms.Add(sender, handle)
            Debug.WriteLine("Child Form Loaded: " & DirectCast(sender, Form).Text)
        End Sub

        Private Sub MDIChild_Remove(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim handle As String = DirectCast(sender, Form).Handle.ToString
            'Remove from our collection
            Debug.WriteLine("Child Form Closed: " & DirectCast(sender, Form).Text)
            Debug.WriteLine("Child forms: " & colChildForms.Count) '<< -- the count of our child forms
        End Sub

    'Each time you open a new child form, you must attach the handlers:

        Dim frm2 As New Form2
        frm2.MdiParent = Me
        AddHandler frm2.Load, AddressOf Me.MDIChild_Add
        AddHandler frm2.Closed, AddressOf Me.MDIChild_Remove

    'That's all there is to it.  You can update your controls in the MDIChild_Add and MDIChild_Remove events.  The value of colChildForms.Count gives you the number of child forms.
    LVL 85

    Assisted Solution

    by:Mike Tomlinson
    You don't have to maintain your own collection of the children (..but I think you already knew that because you were already using MdiChildren.Length).  Just use AddHandler() as Erick37 has shown to trap the closing of your child forms:

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ' load up some MDI children so we can close them...
            Dim f2 As New Form2
            AddHandler f2.Closed, AddressOf Me.MDIChildForm_Closed
            f2.MdiParent = Me

            f2 = New Form2
            AddHandler f2.Closed, AddressOf Me.MDIChildForm_Closed
            f2.MdiParent = Me
        End Sub

        Private Sub MDIChildForm_Closed(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim f As Form = CType(sender, Form)

            If Me.MdiChildren.Length = 0 Then
            End If
        End Sub

        Private Sub UpdateControlState()
            ' update your menus in here...
        End Sub
    LVL 32

    Expert Comment

    That's a great solution, Idle Mind.
    By disposing the form, the MdiChildren.Length returns the correct value.
    LVL 1

    Author Comment

    THANK YOU! You guys are awesome.

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    Introduction When many people think of the WebBrowser ( control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
    The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now