Jump to content
Xtreme .Net Talk

Child Form Focus


Recommended Posts

Guest afrinspray
Posted

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

Guest afrinspray
Posted

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

Guest afrinspray
Posted

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

  • *Gurus*
Posted

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...

   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...

   Public Sub GotFocus()
     MsgBox(Me.Text & " Got focus")
   End Sub

I hope I am understanding what you need.

Guest afrinspray
Posted

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

  • *Gurus*
Posted

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.

Posted

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.

Guest afrinspray
Posted
Maybe the MDI Form is always considered to be the active form for the application?
Guest afrinspray
Posted

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

Guest afrinspray
Posted
Ah yes, the Overridable OnGotFocus! Has anyone used this function before for MDI child forms?
Guest afrinspray
Posted

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

Guest afrinspray
Posted (edited)

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...

 

    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.

Edited by Thinker
Guest afrinspray
Posted
On a side note, how do I indent in this web site? Do I have to use spaces?
Guest afrinspray
Posted
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!
Guest afrinspray
Posted
Ok, thanks, so does anyone have any idea why I'm getting two active Mdi child Forms?
  • *Gurus*
Posted

No, but your code could be better. I don't understand why you're trying to hide an MDI Child form that is losing the focus. That doesn't make any sense to me. Under normal MDI operations, the parent MDIChildActivate will fire when the focus changes from one MDI Child to another, or when the last child is closed.

 

You don't have to have an array of names to check which form is the active one, instead you can use the Is operator to check object equality:

 

If Me.ActiveMDIChild Is frmObjectArray(1) Then

 

If you really must hide a child that goes out of focus, you could perhaps try the BeginLayout and EndLayout methods of the parent form, to indicate you're performing a multi-step operation and it shouldn't redraw or raise certain events.

MVP, Visual Developer - .NET

 

Now you see why evil will always triumph - because good is dumb.

 

My free .NET Windows Forms Controls and Articles

Guest afrinspray
Posted

Cool, I'll implement the object comparison change.

 

I can't find the BeginLayout or EndLayout methods anywhere. Are these in the vb library or do I have to write them myself?

Guest afrinspray
Posted
Did you mean the AddHandler, RemoveHandler functions?
Guest afrinspray
Posted

I figured out a solution! Say I have the following forms: i-1, i and i+1, where i-1 is behind i which is behind i+1. In this example, i+1 is the active form. Before, when I'd click on i, my program would hide the top level form (i+1) and then automatically activate the i-1 form for some bizarre reason that I can't figure out. Then, the i form would also be activated, so I'd have to active looking windows, i-1 and i.

 

To fix the problem I explicitly told VB to activate both mdi forms in the order that I wanted them to be activated. So, I said

 

frmObjectArray(i-1).Activate()

frmObjectArray(i).Activate()

 

where frmObjectArray is my "collection" of forms. This is a total hack but it's the only way I could get only one form activated at once. Maybe someone has a better idea? I don't know, but it works- thanks for all the help.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...