Set Focus & Visible = False

sly like Coyote

Registered User.
Local time
Today, 09:46
Joined
Apr 14, 2010
Messages
82
I'm having problems setting the visibility of a command button to false after it's been clicked, and I'm not sure why.

When the user clicks the button, it's supposed to finish the on click sub by setting focus into the subform that becomes visible as a result of the click, and then set visible = false. I make sure the subform is visible before setting focus, and make sure to mention the control specifically when doing the Set Focus call. I still get the 2165 Error "You can't hide a control that has the focus".

I've tried multiple different setups for setting the subform visibility (which works fine every time) setting the focus (which apparently doesn't, even though I know the sub is getting called and not returning errors) and setting the visibility of the command button.

I'm pretty sure the problem lies with the SetFocus not taking effect before the visibility = false is called, but I've tried using a repaint as recommended in the Set Focus docs and that still didn't solve the problem. Anyone have any idea what's going wrong?
 
Try setting focus to your subform just after making it visible. Then set focus to the desired control on the subform, then hide or disable your command button after the focus has been set to some other object.
 
I initially tried setting focus on the subform itself, which didn't work. Checking the VBA documentation makes it sounds like this won't be allowed if any of the controls on the form are enabled, which they are. I've even tried adding the SetFocus sub via the On Load events for the subforms, and none of it seems to be working to actually set the focus away from the command button.
 
I could really use some help here. I've read the other threads that come up on search, and I've tried calling the Set.Focus on everything from various subform controls, the subform itself (which returns an error), mainform controls, and in all kinds of places. I've had it called in the OnLoad of the subform, right after setting visilbility of the subform with the command button, immediately prior to setting visibility for the command button itself.

I've tried this redundantly. I've tried this redundantly, follwed with a repaint after every single call. I've tried this redundantly with the repaint every single place that could possibly be activated (and I know they ARE being activated because I've placed message boxes immediately after each SetFocus/repaint call).

I still return this error. As far as I can tell, calling SetFocus does literally nothing. No errors are being returned when it runs through the call, and I've called it during this routine at least four times to assorted trial controls. Nothing happens; it just runs right through that line of code and proceeds to the next.
 
I've got one more idea. I'm going to try to figure out how to run a short delay prior to setting the control visibility. I've used SetFocus before and found it to be very finicky, and I think it might be because there's some kind of hidden 'lag' before it actually takes effect. Can anyone confirm if this is the case?

There's nothing in the documentation about it, but the recommendation for the repaint call makes me suspect this might be an issue, and I've heard some reports that tossing in a short delay can stop this error from occuring sometimes.

[Edit]
Reading the documentation more closely, I think I may have found the problem. The relevant section:

You can move the focus only to a visible control or form. A form and controls on a form aren't visible until the form's Load event has finished. Therefore, if you use the SetFocus method in a form's Load event to move the focus to that form, you must use the Repaint method before the SetFocus method.

It looks like I've being doing the Repaint operation in the wrong place - it's not meant to force an update after SetFocus method itself to get it to take effect, but to force the form to finish the load event so that SetFocus can actually be called. Why the error message doesn't call there when SetFocus fails is utterly beyond me, but I think I've IDed my main problem.

This would also explain why a short delay after the visible = true call on the subform would solve the problem, since it would allow the load to complete so the SetFocus works properly.
 
Last edited:
could you post some code.. so we can take a look at it?
 
Hmm, definitely something strange going on. I moved the Visible = False into the LostFocus event of the command button. This was called, and returned the same error. This happened before the visibility settings for the subform were called during the OnClick event.

I'll try to upload an empty version of the database at some point if I can't get it figured out.
 
Just a swag here ... is the button Default property set to Yes? If so, try setting it to No to see if that cures.

-dK
 
Default set to no. This is the relevant part of the code as I initially worked it and what I've reverted to as I try to debug since it's the simplest...
Private Sub cmd_NewRecord_Click()
'Update display based on landlord_type definition
'set display to first field of appropriate subform
UpdateSubformDisplay
If cbo_LandlordCategory = "Individual" Then
Me.frm_IndividualLandlords.Form.Repaint
Me.frm_IndividualLandlords.Form.p_fname.SetFocus
ElseIf cbo_LandlordCategory = "Company or organization" Then
Me.frm_CompanyLandlords.Form.Repaint
Me.frm_CompanyLandlords.Form.company_name.SetFocus
End If
'Replace record navigation tools with save/abandon new record controls
DataEntryDisplay
'Remove the new record command button from the header
cmd_NewRecord.Visible = False
End Sub

I tossed MsgBox statements into the GotFocus and LostFocus events of the command button, and the results are pretty confusing. The control gets the focus when clicked, then loses the focus as the subform finishes diplaying. This makes sense, as I've got SetFocus calls for controls on those subforms. Unfortunately, the focus is immediately shifted back to the command box.

I've checked through and can't find a SetFocus call pointing to the command button anywhere in my database, so I'm a bit stumped as to why it's happening.
 
I would guess that these steps ....

Code:
'Replace record navigation tools with save/abandon new record controls
DataEntryDisplay
'Remove the new record command button from the header
cmd_NewRecord.Visible = False

could be the issue. I am assuming that the DataEntryDisplay bit is a function that does some tricks? After the the screen is reset with the save/abandon new record controls the form is refreshed in there somewhere and then you are trying to set the button to invisible.

By this assumption since the command button is in the header it is receiving the focus (perhaps tab stop #1?).

Try setting the focus somewhere else after you call the DataEntryDisplay bit and see if that works.

What I usually do is to create a new command button, call it cmdFocus (tab stop #1), set its transparency on and always use it to set the focus on if I am trying to do some sleight of hand stuff.

Just an idea.
-dK
 
Yeah, that sub just sets the visibility of other controls in the header - removes the record navigation tools and displays the save/discard buttons for the new record. I've tried it with that commented out and get the same results.

Your idea with the hidden command gave me an idea, though - set the focus to one of the newly displayed controls after display is adjusted. Worked like a charm - focus stuck to the other command box, and the visibility settings for the control giving me problems worked perfectly. Code ended up changing to

'Replace record navigation tools with save/abandon new record controls
'Set initial focus to cancel button
DataEntryDisplay
cmd_DataEntryCancel.SetFocus
'Remove the new record command button from the header
cmd_NewRecord.Visible = False

As an experiment, I then tried dropping the focus into the subform and experienced the same problem with the command losing and then regaining focus. I don't know what's going on there, and I'm darn glad I don't need to figure it out to get this working.
 
Ah ... I just learned recently that a subform can't receive the focus so there ya go.

Glad it worked out for you.

-dK
 
Final update on this: it is possible to shift the focus down into the subform, but the syntax for doing so is really strange. You need to initially SetFocus to the subform control; after this you can set focus to the control you actually want to end up on.

This is incredibly counterintuitive, especially since referring to the subform itself returns an error (why I'm not sure), and referring directly to the control within the subform seems to do nothing whatsoever. Final working code is below.

'Update display based on landlord_type definition
UpdateSubformDisplay

'set focus into correct subform
If cbo_LandlordCategory = "Individual" Then
Me.frm_IndividualLandlords.SetFocus
Me.frm_IndividualLandlords.Form.p_fname.SetFocus
ElseIf cbo_LandlordCategory = "Company or organization" Then
Me.frm_CompanyLandlords.SetFocus
Me.frm_CompanyLandlords.Form.company_name.SetFocus
End If

'Replace record navigation tools with save/abandon new record controls
'Set initial focus to cancel button
DataEntryDisplay

'Remove the new record command button from the header
cmd_NewRecord.Visible = False
 
Ahhhh ... hmmmm .... Yes, very counterintuitive like you said.

Thanks alot for posting back your final solution!

-dK
 
I think you're getting an error because when focus switches to the subform object, focus immediately goes to the first-in-tab-order object on the subform, so the subform object itself loses focus, then you can't refer to the command button because it's on a different form.

If it was me, I'd have put subform.visible=true in the on click of the button, then command button.visible=false in the gotfocus event of the subform.
 
I think you're getting an error because when focus switches to the subform object, focus immediately goes to the first-in-tab-order object on the subform, so the subform object itself loses focus, then you can't refer to the command button because it's on a different form.

If it was me, I'd have put subform.visible=true in the on click of the button, then command button.visible=false in the gotfocus event of the subform.
This was not the problem; the error was not a reference error, it was tied to attempting to set visibility while the control had focus.

The basic problem here was with trying to do the Set Focus into the subform with a single line of code: if you want to set focus to a control that's not on the current form, you HAVE to select the container of the other form first. I've tried this several times since to clean up tabbing in and out of subforms, and this is true at every point.

I tried something very close to what you suggested with the single SetFocus call, and returned the same error. I suspect it would work as long as you included the setfocus call to the subform control.
 
Last edited:

Users who are viewing this thread

Back
Top Bottom