Child Form Focus

  • Thread starter Thread starter afrinspray
  • Start date Start date
A

afrinspray

Guest
Hey,

While switching between Mdi Child forms, what event handler determines which one has focus? I'm a little confused why this event:

Private Sub Blah1_Activated(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Activated

is not controlling the focus gain of the form Blah1.

Thanks,
Mike
 
I did, and it's not working at all. :( The code looks fine, and the program compiles, but when the form is given focus, both Activated and MdiChildActivate don't respond to the event! Do I have to somehow associate the form with the event (other than using the "Handles MyBase.<Activated or MdiChildActivate>")?

Thanks,
Mike
 
Just let the code designer generate the subs for you.. what you want it the MdiChildActivate event of the parent form.
 
Ok,

In the MDI form, I used the mdichildactivate event, which works, but now I have to rethink how I am going to do this. What I would really like is to have an event in the MDIChild form which is triggered when the form is activated; however, activated doesn't work because the MDI form is always the active form (I guess, I can't think of any other reason for this).

Thanks,
Mike
 
One possible way to handle it is add a public sub to your mdichild
class and in the MDIChildActivated event call that sub. Let's say
that the mdichild class is called myMDIChild and the sub is GotFocus.
In the parent it would be...
Code:
    Private Sub MDIChildActivated(ByVal sender As Object, ByVal e As System.EventArgs) Handles MainForm.MdiChildActivate
      Dim temp As myMDIChild
      If (Me.ActiveMdiChild Is Nothing) Then
        'being closed
      Else
        temp = CType(Me.ActiveMdiChild, myMDIChild)
        temp.GotFocus()
      End If
    End Sub
Then in the myMDIChild class...
Code:
    Public Sub GotFocus()
      MsgBox(Me.Text & " Got focus")
    End Sub
I hope I am understanding what you need.
 
Yes, it would probably help if I said exactly what I am trying to do. :)

I have an MdiForm with 8 different child forms that each have a listbox filled with values from a database. When the program starts (from the MdiForm), only the first child form is displayed (form 0). After the user selects a value from the listbox (in this first child form), a new form (form 1) is displayed a few pixels down and over from the previous form (form 0). Form 1's listbox values depend on the previous selection from Form 0. The user then selects another value from the new form (form 1), and then a new form (form 2) is displayed with more values in a listbox. This activity continues...

Also, other than sharing the common listbox feature, each of these child forms is unique.

While the user is interacting with my program, they should have the option of returning to a previous ChildForm. I want them to be able to do so by clicking on the inactive windows in the background. For example, if they are currently viewing form 4, and they would like to return to form 2, all they would have to do is click on form 2 (which is inactive), then form 4 and form 3 would automatically dissappear.

The problem I have is that it's hard to refer to other forms unless I was storing a copy of them somewhere, which seems inefficient. Is there a way to scroll through the different MDIChildForms? If so, it might be possible to use your method. I am trying to get away from the Upgrade Wizard's method of using Default Instances (DefInstance) because that just seems like bad programming practice. In VB6, this would be easy, since I could just say Form4.Hide and Form3.Hide.

Thanks so much for the help thus far,
Mike
 
Well, the reason you can say Form4.Hide or Form3.Hide is
because VB6 automatically creates global object references for
you (including the Forms collection). So it really wouldn't be
inefficient for you to merely duplicate in code what VB6 was doing
whether you needed it or not. In this case however, it appears
that the mdi parent already holds a collection of mdichildren
(referenced as Me.MdiChildren). So, you should be able to use
that collection to determine what forms are loaded, etc.
 
hi guys - thanks thinker, you just solved me a riddle...

mdiChildren - couldn't see the wood for the trees...

can anyone explain why the activate/deactivate in the base classes don't work when a form is a child form?

if i use the overrides 'onActivate' handler this works weather the form is an mdichild or not?

cheers,
drew.
 
This is really pissing me off. There must be a way to tell whether an MDI form has focus from inside it's own code.

Just picture this scenario. At some point in the execution of a program, three mdi child forms are open. If the user clicks one, the others are hidden. How would you go about hiding the other ones Using the MdiChildActivate event? There is no clean way because when you use the .hide() that form also becomes active. This damn recursion like crap is killing me! I hate using flags (global booleans) because it's really confusing for others to read.

There must be a way, does anyone have a solution to my problem?

Thanks,
Mike
 
Ah yes, the Overridable OnGotFocus! Has anyone used this function before for MDI child forms?
 
Cannot Activate MDIChildForms

How can an MDIChildForm respond to being activated? Is MDIChildActivate the only way? In other words, what other event handles MdiChlid activation? I need one that can be placed INSIDE the mdi child...

Thanks,
Mike
 
I don't understand what your problem with using the MDIChildActivate event of the parent form is. If you're desperate for code in a child form to run on this event, just run it from the parent form!
 
Ok Here's the problem. When I have three child forms open (say the third form is active, the second form is behind the third, and the first behind the second), and I click on the second form, I want to hide the third form. Unfortunately, before VB hides the third form, the second form goes behind the first. Then, once the third form is hidden, the first form becomes active, calling the MdiChildActivate event again. I can stop this recursion by using a boolean variable, but I can't think of any other way...

Visual Basic:
    Private Sub theMdiForm_MdiChildActivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.MdiChildActivate

        Dim i As Integer 'This variable is used for incrementing.
        For i = 0 To 7
            If ActiveMdiChild.Name = strFormNameArray(i) Then
                setTheCurrentFormNumber(i)
                Exit For
            End If
        Next
        'This function contains the code for when 
        If blnDoNotRecurse = False Then
            Call goBackToSelectedForm()
        End If
        blnDoNotRecurse = False

    End Sub

'Here's the goBackToSelectedForm() function located in a module:

    Public Sub goBackToSelectedForm()
        blnDoNotRecurse = True
        Dim i As Integer 'This variable is used in the for loops below.
        Select Case theMdiForm.DefInstance.ActiveMdiChild.Name
            Case strFormNameArray(0)
                For i = 1 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(1)
                For i = 2 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(2)
                For i = 3 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(3)
                For i = 4 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(4)
                For i = 5 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(5)
                For i = 6 To 7
                    If (Not frmObjectArray(i) Is Nothing) Then
                        frmObjectArray(i).Hide()
                    End If
                Next
            Case strFormNameArray(6)
                If (Not frmObjectArray(7) Is Nothing) Then
                    frmObjectArray(7).Hide()
                End If
        End Select

    End Sub

The frmObjectArray is my implementation of the old VB6 forms collection. The strFormNameArray contains the names of all the forms which will at some point be initialized and referenced in the frmObjectArray.

Thanks so much for the help thus far. If you don't understand any of my code, please tell me, I'll try to explain it better.
 
Last edited by a moderator:
Oh yeah I forgot to mention that in the example above, the First forms title bar turns active!!!!@!#!#! So I actually have two active forms!
 
Ok, thanks, so does anyone have any idea why I'm getting two active Mdi child Forms?
 
Back
Top