views:

304

answers:

2

I usually call myControl.Focus() in the Loaded event handler, but this doesn't seem to work for a ListBox which is databound to a list of custom objects. When I start my application, the ListBox's first item is selected but the focus is elsewhere.

I thought this could be because the focus is being set before the databound items are loaded into it... but the following code shows that there are indeed items because ctrlItemsCount shows the number 8.

How can I set the initial focus in this situation, and what is the correct place to set initial focus usually?

private void onLoad(object sender, RoutedEventArgs e) {
        if (ctrlCountries.Items.Count > 0) {
             ctrlItemsCount.Text = ctrlCountries.Items.Count;
             ctrlCountries.SelectedIndex = 0;
             FocusManager.SetFocusedElement(this, ctrlCountries);
        }

  }

EDIT: I have moved this code to the loaded event for the actual ListBox itself. It almost works - the focus is now on the ListBox, but I still need to press keyboard DOWN once before item #0 has the keyboard cursor. In other words, the focus, or cursor, is 1 notch above item #0 for some reason:

private void onCountriesLoaded(object sender, RoutedEventArgs e) {
    ctrlCountries.SelectedIndex = 0;
    FocusManager.SetFocusedElement(this, ctrlCountries);
    Keyboard.Focus();
}
+1  A: 

The FocusManager.SetFocusedElement method gives logical focus, but not keyboard focus. You can use the Keyboard.Focus method to give keyboard focus to an element. Have a look at this page for more details about focus management in WPF.

Thomas Levesque
I added Keyboard.Focus(ctrlCountries); and it doesn't work.Note that if I add a button click event handler which sets focus with the focus manager alone, it works.
PRINCESS FLUFF
In other words, the following code does not put the focus on the listbox first item:private void onLoad(object sender, RoutedEventArgs e) { FocusManager.SetFocusedElement(this, ctrlCountries); Keyboard.Focus(ctrlCountries); }
PRINCESS FLUFF
Do it after the ListBox is fully loaded (i.e. when the ctrlCountries.Loaded event occurs)
Thomas Levesque
Thanks, this is much better now. But the cursor is still on the outside of the ListBox (ie. its border seems to have the focus), so I have to hit DOWN before the first listbox item is selected.
PRINCESS FLUFF
+2  A: 

If you want to focus the first element in the list box you have to set the focus to the first ListBoxItem container. For example:

if (myListBox.Items.Count > 0)
{ 
   ListBoxItem item = (ListBoxItem)myListBox.ItemContainerGenerator.ContainerFromIndex(0);
                FocusManager.SetFocusedElement(this /* focus scope region */, item);
}

You still have to make sure though, that the ListBox control has first received its Loaded event. There are a number of other events that are useful for handling list box item related updates. Have a look at the ItemContainerGenerator in MSDN.

olli
It works! Almost... It works 100% as it should if I use "Keyboard.Focus(item);" instead of the FocusManager. This is odd because MSDN says the FocusManager will set the logical focus AND attempt to set the keyboard focus. Am I learning the correct lesson that Keyboard.Focus(item) is what I should always use then?
PRINCESS FLUFF