[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 484
  • Last Modified:

MDI child windows

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
            mainWin.UpdateControlState()
        End If

    End Sub

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

Thanks






0
k3n51mm
Asked:
k3n51mm
2 Solutions
 
Brian CroweCommented:
If you do a trace or step through your code I believe you will find that the MDIClient is your mysterious window.
0
 
Erick37Commented:
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
        colChildForms.Remove(handle)
        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
    frm2.Show()


'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.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
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.Show()

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

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

        If Me.MdiChildren.Length = 0 Then
            Me.UpdateControlState()
        End If
    End Sub

    Private Sub UpdateControlState()
        ' update your menus in here...
    End Sub
0
 
Erick37Commented:
That's a great solution, Idle Mind.
By disposing the form, the MdiChildren.Length returns the correct value.
0
 
k3n51mmAuthor Commented:
THANK YOU! You guys are awesome.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now