Solved

How to know what MDI Child Form just closed ?

Posted on 2006-06-14
9
1,678 Views
Last Modified: 2013-07-26
VS2005

Situation:
MDI Parent with several child forms. All forms can only be instantiated once (already have the code for this).
There is a childform which opens another childform.
without MDI, i could call this other form with ShowDialog, and use the DialogResult as a trigger in the calling form to know when the form is closed, so I can trigger a reaction.


Now, since I moved the app. to an MDI app, I can not use the ShowDialog anymore since I want all the forms INSIDE the MDI application. I don't want to work around that.

The events of the MDIParentForm include an MdiChildActivate event, but it does not include an MdiChildClose event.

So, the question boils down to the title: how can I know know what MDI Child Form just closed ? Is there an event for it, somewhere ? Can I attach an event to something ?

Or do I have to revert to writing a function in my MDIParent which I call from all the FormClosed() events of the child form ?
As a last thing, I really don't want to use a timer for this, unless it is the best solution proposed by the Experts.

thx in advance,

cheers,
Andy
0
Comment
Question by:AndyAelbrecht
9 Comments
 
LVL 6

Expert Comment

by:manch
Comment Utility

Add handler of the Child Form Closed Event (on the MDI Form)

Open the child form as
Dim mobjFrm as ChildForm withevents

In Mdi Form (or other child Form use)
mobjFrm.Show

write the sub on the MDI Form

    Private Sub MDIChild_Closed(ByVal sender As Object, ByVal e As System.EventArgs) _
                Handles mobjFrm.Closed
        '------------------------------------------------------------------------
        'Subroutine Name    :   MDIChild_Deactivate
        'Purpose            :   This Event Receives closed Event of all MDI children   forms
        'Created By         :   Hemant Patidar
        '------------------------------------------------------------------------

        'Removing the Form Memory Space
        SetNothing(CType(sender, Form))

    End Sub

0
 
LVL 4

Author Comment

by:AndyAelbrecht
Comment Utility
yes, I see this working.

but there are several forms being opened by several other forms (all MDI children).
so I have to expand this code to work for all of them, right ?

another thing: Dim myform as New frmOfferteNieuw withevents doesn't work for me; I was already using this approach without the withevents behind it.
but if I add it, it breaks :( (says end of statement expected) (even when i remove the New keyword)
0
 
LVL 4

Author Comment

by:AndyAelbrecht
Comment Utility
Dim WithEvents myform as New frmOfferteNieuw does work, however.

Ok, now that this is out of the way:


Your MDIChild_Closed function looks cool, but it depends on 1 specific form; I need to be able to capture the close event of any MDI Child form that I open.
0
 
LVL 4

Author Comment

by:AndyAelbrecht
Comment Utility
damn i'm sorry for this mistake:
Dim Withevents does not work as "WithEvents is not valid on a local variable declaration".

Which means I have to publicly declare all my possible Child forms in my MDIParent form, right ?
0
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.

 
LVL 2

Expert Comment

by:Mystify
Comment Utility
You can create a delegate.

on your child form, add the following:

#Region "Delegates"
        Private m_DelegateObject As Object    ' This is the object that will store the function it's supposed to call.
        Public Property DelegateObject() As Object    ' A property to get and set the delegate object
            Get
                Return m_DelegateObject
            End Get
            Set(ByVal value As Object)
                m_DelegateObject = value
            End Set
        End Property
#End Region


Now, in your child form closing event, add this:

If Not DelegateObject Is Nothing Then DelegateObject.Invoke(Me)




Now, on your parent form, create a sub or functin that you want to be the routine that is called when a child form is closed:

    Private Sub MDIChildClosing(ByVal Child As Form)
        MsgBox("Form " & Child.Name & " is closing")

        ' IF you need to access a unique variable or property in the form that
        ' is not a member of the generic "form" object, you can do a type convertion
        ' to the form itself to access them.

        Select Case Child.Name
            Case "ChildForm1" : MsgBox("My customer property value is " & CType(Child, ChildForm1).MyCustomProperty)
        End Select
    End Sub




Now, on your parent when ever you open your child form, you need to give the form the address of your sub. To do this, you do the following

ChildForm1.DelegateObject = AddressOf MDIChildClosing

Now, when your child form closes, it will call the sub MDIChildClosing on the parent, thus allowing the parent to to process the fact the the child is closing.


This is how you "pass" a function or sub from one object to another, and have it "run" on the parent. Just make sure that if you change the parameters of your sub that you change them in your child's call too.

I am using the form itself as the variable that I am passing, but you can use anything...
if DelegateObject.Invoke(Me) doesn't work (which may not because you are passing the object that is closing) then just do a me.name instead and change the MDIChildClosing paramters to "Name as string" instead of "Child as form" and process however you are comfortable.

0
 
LVL 4

Author Comment

by:AndyAelbrecht
Comment Utility
Mystify, thank you very much for this info.

While trying to implement it I'm running into some small problem(s) here.

First thing is that it's not my parent form which is opening new MDI child forms, it's other MDI children opening them.
So, I've put the Delegate in my MDI children that need to notify the parent that they're down.
I've put the Child form code in the child form.

but now, the last missing link, is the delegateobject. I have setup the another MDI child with this code:

        If Not IsChildInMemory("frmKlantNieuw") Then
            Dim myform As New frmKlantNieuw
            myform.DelegateObject = AddressOf MDIStartForm.MDIChildClosing
            myform.MdiParent = Me.MdiParent
            myform.Show()
        End If

this code worked, but when i added the delegateobject line, it gives me this: 'AddressOf' expression cannot be converted to 'Object' because 'Object' is not a delegate type. Thus, it's not working just yet.
Also, as a sidenode, I didnt get intellisense on the DelegateObject.Invoke(Me) (as in: it didnt know the invoke function. it isnt complaining either though)
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
Comment Utility
So you basically need to simulate a ShowDialog() call but with MDI children?...

(1) Disable you current form
(2) Create the new child form
(3) Use AddHandler() to trap the Closing() event (FormClosing() in VB2005) of the new child form
(4) Show the new child form
(5) Re-enable the calling form when the new child form is closed

The only caveat is whether you need just the calling form disabled or all other child forms disabled.  If you need all disabled then we need to make a sub in the MDI parent to do this but it's not that much more work.

(A) First version - Only calling form is disabled...

    Public Class someMdiChild

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MdiChild.Click
            Me.Enabled = False
            Dim md As New MdiDialog
            md.MdiParent = Me.MdiParent
            AddHandler md.FormClosed, AddressOf Me.md_FormClosed
            md.Show()
        End Sub

        Private Sub md_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs)
            Me.Enabled = True

            ' grab some info off the "Mdi Dialog" that was just closed
            Dim md As MdiDialog = CType(sender, MdiDialog)
            Me.TextBox1.Text = md.TextBox1.Text         End Sub

    End Class


(B) First version - All MDI Children are disabled...

    Let me know if you need to see this.
0
 
LVL 4

Author Comment

by:AndyAelbrecht
Comment Utility
Idle_Mind, you have always been my hero in VB.net :)

i didnt need all the enabling or disabling, i just needed to be able to know what form has been closed so I can act on it (ie: refresh my datasets in other forms)

but the rest of your code is working 100% fine.

thank all 3 of you for your help, but i will move all points to Idle_Mind, as he perfectly answered my Q :)

now, if one of you would be so kind as to answer my other question aswell (Cut/Copy/Paste and basic undo in MDI children), I would be the happiest dude alive :-D

cheers,
Andy
0
 
LVL 1

Expert Comment

by:PriceConsulting
Comment Utility
I have been looking for this solution for a long time....thank you so much...worked great!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

763 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

10 Experts available now in Live!

Get 1:1 Help Now