views:

1182

answers:

2

I have a custom UserControl (a label and a textbox).

My problem is I need to handle the key down, key up events to navigate between controls in the form (.NET Compact Framework textbox, combobox, etc). With the controls provided by the .NET Compact Framework framework it works, but when I reach a usercontrol written by me, that control don`t get focus (the textbox inside get the focus) so from this usercontrol I cannot navigate because in the panel I don't have any control of who have focus.

A little mock up : Form->Panel->controls -> on keydown event (using KeyPreview) with a foreach I check what control have focus on the panel and pass to the next control with SelectNextControl, but no one have focus because the usercontrol don`t got focus...

I tried to handle the textbox gotFocus event and put focus to the user control, but I got an infinite loop..

Does somebody have any idea what can I do?

A: 

It's normal that your panel doesn't receive any focus. What you can try is to look if any children of your usercontrol contains the focus. Something like this:

bool ContainsFocus(Control lookAtMe) {
 if (lookAtMe.Focused) return true;
 else {
     foreach (Control c in lookAtMe.Controls) {
         if (c.Focused) return true;
     }
 }
 return false;
}

You could also traverse them recursively if that's needed, but I don't think that's one of your requirements here.

Stormenet
+3  A: 

We've done the exact same thing on Compact Framework, adding a global focus manager that supports navigating between controls using keyboard input.

Basically, what you need to do is to recurse down the tree of controls until you find a control that has focus. It's not terribly efficient, but as long as you only do it once per key event, it shouldn't be an issue.

Edit: Added the code for our recursive focus finding function:

public static Control FindFocusedControl(Control container)
{
    foreach (Control childControl in container.Controls) {
        if (childControl.Focused) {
            return childControl;
        }
    }

    foreach (Control childControl in container.Controls) {
        Control maybeFocusedControl = FindFocusedControl(childControl);
        if (maybeFocusedControl != null) {
            return maybeFocusedControl;
        }
    }

    return null; // Couldn't find any, darn!
}
Freed
Thank you! (need more five char from the system to let to add this comment)
Alex
Sweet Answer. This is one of the few reliable ways to get the focus.
Vaccano
why iterate a control twice?
thephpdeveloper
@thephpdeveloper - It will basically make the difference between a Breadth First Search and a Depth First Search, our assumption was the the first approach would terminate quicker most of the time.
Freed
ah yes i see it now. I have something against double iterations, so forgive me
thephpdeveloper