How to know when a Container Control loses focus?

In my Windows app, I have a listbox showing various records on a page panel. When a record is selected, the corresponding detailed data for that record is shown using various textfields in a container control. I allow the user to change the data within the container control and have provided a save button to update a database. This works fine if the user clicks the save button after changes are made. It doesn’t work if the user clicks elsewhere (like a new row or goes to a different page panel). I thought I could use the lost focus event of the container control to test to see if the data was saved, but that event just doesn’t work.

Is there any other way I can check to see if the container control has lost the focus so I can test to be sure the user’s changes where saved?

– Rob

http://documentation.xojo.com/index.php/ContainerControl.AcceptFocus

I have already tried that and the event does not fire.

One of the controls in the container probably has focus and so its lost focus event might be raised
You could add an event to the container “LostFocus” and then just raise that from the lost focus events in the controls in the container

I’m scratching my head about why GotFocus/LostFocus was implemented for a ContainerControl. It was obviously a deliberate act, as the docs for AcceptFocus explicitly mention ContainerControl. When and how does it make sense to think of the Container getting focus? The controls in the container can get focus, but the container itself? I don’t understand how that makes any sense.

This has already bee reported as <https://xojo.com/issue/15333>.

I would bet that it was implemented because Containers are ‘special’ windows. Since a window has that event containers do too.

But you’re right. It makes no sense. I’d prefer that the events go away because people want to use them.

Norm pretty much described what is going on in my app. The problem with his solution is that I have several controls in the container control. If the user moves from one control to another in the container, the control loses focus, but the container hasn’t really lost the focus. It only loses the focus if another control outside the container receives the focus, except this is not reported (by design).

So, any ideas then on how to know when a control outside a container control receives the focus?

Could you maybe put it into a Canvas and have the Canvas check for got/lost focus?

You’d still have the same problem. The canvas would never “get focus”, just the controls in the container. To make this work right, you have to trap every possible way the user can change focus - mousedown and keydown of every control - to determine when focus is switching from inside the container to outside and then 1) validate the contents of the container, and 2) either alert the user (and disallow the focus change?) or update the record.

I hope I am understanding properly your problem and I am not proposing a too stupid idea here… : what about having a flag/boolean property that will be set to true when any of the controls on the container control loses focus and they will set it to false when they get focus. Also, every time one of the controls loses focus set a timer to fire almost inmediately and check for the value of the flag. If the flag is true one control lost focus and no other control of the container control got it.

Julen

Yep, good point.

Could not to some extent MouseEnter and MouseExit replace focus ? Admittedly, while the mouse is over the canvas could be construed as focus ?

Won’t a flag could be used that tracks both mouse hovering the canvas, and focus on each control within it ?

Container controls have a “focus” property (same as a window)
And that is the currently focused control - whether its in the CC or not
So you could check that “focus” is one of the controls in the CC and if so then it has focus and if not it doesn’t

Something like

  • create a new desktop project

  • add container control

  • add two event definitions GotFocus & LostFocus

  • add a text field & text area to the container control

  • in the lostfocus event of those two controls put
    if focus = textArea1 or _
    focus = textField1 then
    return
    end if

    raiseEvent LostFocus

  • in the got focus events of those two controls put

    if self.focus = textArea1 or _
    self.focus = textField1 then
    raiseEvent GotFocus
    end if

  • put an instance of the cc on the default window

  • put some other controls on the window outside the cc that can get focus (more text fields & text areas)

  • implement the GotFocus & LostFocus events of the cc

That should cover it
Note that for Windows you’;ll also have to check buttons & other controls that can also get & lose focus

Norm –

I tried what you mentioned but I can’t get it to work. I may have implemented the GotFocus and Lost Focus event/event defintion incorrectly. Also, the Focus property is returning Nil. Could it be that the control has lost focus but the next control has not yet received it, therefore the Focus property is Nil?

– Rob

focus could be nil
that’s possible

without seeing how you implemented it I cant be sure whats wrong but when I did this it worked reasonably

Can you post a sample project? I understand what you suggested, but I have no coding experience with event definitions, etc.

Here is my sample project. I only implemented the LostFocus as that’s all I need for now. Perhaps someone can give their thoughts on why it is not working.

– Rob

https://www.dropbox.com/s/7h7xtruv9suxmrj/LostFocusExample.xojo_binary_project

It does not work on windows because the Window.Focus property = nil in the Lostfocus event

Which lostfocus ? The window, the controls ? The controls within the container control ?

If the window lost focus, it makes sense its focus property is nil or false.