Solved

How to know what MDI Child Form just closed ?

Posted on 2006-06-14
9
1,708 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
ID: 16901004

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
ID: 16901034
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
ID: 16901061
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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 4

Author Comment

by:AndyAelbrecht
ID: 16901070
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
 
LVL 2

Expert Comment

by:Mystify
ID: 16901771
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
ID: 16902298
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
ID: 16902307
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
ID: 16902386
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
ID: 39359520
I have been looking for this solution for a long time....thank you so much...worked great!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
RLDC Reporting in Visual studio 11 30
FInd Image Control Gridview 3 23
VB.net Open video relating to control 2 20
How to repeat the data 4 20
Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

820 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