Solved

How to know what MDI Child Form just closed ?

Posted on 2006-06-14
9
1,761 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
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 86

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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
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…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

623 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