Guest afrinspray Posted July 15, 2002 Posted July 15, 2002 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 Quote
*Gurus* Thinker Posted July 16, 2002 *Gurus* Posted July 16, 2002 I would look into the MdiChildActivate event. Quote Posting Guidelines
Guest afrinspray Posted July 16, 2002 Posted July 16, 2002 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 Quote
*Gurus* divil Posted July 16, 2002 *Gurus* Posted July 16, 2002 Just let the code designer generate the subs for you.. what you want it the MdiChildActivate event of the parent form. Quote 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 July 16, 2002 Posted July 16, 2002 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 Quote
*Gurus* Thinker Posted July 16, 2002 *Gurus* Posted July 16, 2002 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. Quote Posting Guidelines
Guest afrinspray Posted July 16, 2002 Posted July 16, 2002 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 Quote
*Gurus* Thinker Posted July 16, 2002 *Gurus* Posted July 16, 2002 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. Quote Posting Guidelines
paynea Posted July 18, 2002 Posted July 18, 2002 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. Quote
*Gurus* Thinker Posted July 19, 2002 *Gurus* Posted July 19, 2002 If you are asking why events like Activated don't fire in the Child, then all I can say is, Good Question. There is probably a perfectly logical reason for it, but I can't find it right now. Quote Posting Guidelines
Guest afrinspray Posted July 22, 2002 Posted July 22, 2002 Maybe the MDI Form is always considered to be the active form for the application? Quote
Guest afrinspray Posted July 22, 2002 Posted July 22, 2002 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 Quote
Guest afrinspray Posted July 22, 2002 Posted July 22, 2002 Ah yes, the Overridable OnGotFocus! Has anyone used this function before for MDI child forms? Quote
Guest afrinspray Posted July 25, 2002 Posted July 25, 2002 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 Quote
*Gurus* divil Posted July 26, 2002 *Gurus* Posted July 26, 2002 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! Quote 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 July 26, 2002 Posted July 26, 2002 (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 July 27, 2002 by Thinker Quote
Guest afrinspray Posted July 26, 2002 Posted July 26, 2002 On a side note, how do I indent in this web site? Do I have to use spaces? Quote
Guest afrinspray Posted July 26, 2002 Posted July 26, 2002 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! Quote
*Gurus* Thinker Posted July 27, 2002 *Gurus* Posted July 27, 2002 Put your code inside of [code][/code] tags, or you could try the new [vb][/vb] tags, but they mostly understand VB6 keywords. Quote Posting Guidelines
Guest afrinspray Posted July 27, 2002 Posted July 27, 2002 Ok, thanks, so does anyone have any idea why I'm getting two active Mdi child Forms? Quote
*Gurus* divil Posted July 28, 2002 *Gurus* Posted July 28, 2002 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. Quote 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 July 29, 2002 Posted July 29, 2002 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? Quote
Guest afrinspray Posted July 29, 2002 Posted July 29, 2002 Did you mean the AddHandler, RemoveHandler functions? Quote
Guest afrinspray Posted July 29, 2002 Posted July 29, 2002 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. Quote
*Gurus* divil Posted July 29, 2002 *Gurus* Posted July 29, 2002 I really don't follow your problem at all. I suspect if you need any more help on this issue you'll have to make a sample project which reproduces your problem and post it. Quote MVP, Visual Developer - .NET Now you see why evil will always triumph - because good is dumb. My free .NET Windows Forms Controls and Articles
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.