2010-02-17 1 views
6

J'appelle généralement myControl.Focus() dans le gestionnaire d'événements Loaded, mais cela ne semble pas fonctionner pour un ListBox qui est databound à une liste d'objets personnalisés. Lorsque je démarre mon application, le premier élément de ListBox est sélectionné mais l'accent est mis ailleurs.Comment puis-je définir correctement le focus sur une ListBox en charge si elle utilise la liaison de données?

Je pensais que cela pourrait être parce que l'accent est mis en avant les éléments de databound sont chargés dans ... mais le code suivant montre qu'il ya effectivement des éléments parce ctrlItemsCount montre le numéro 8.

Comment puis-je définir le focus initial dans cette situation, et quel est le bon endroit pour définir le focus initial habituellement?

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: Je suis déplacé ce code à l'événement chargé pour le ListBox réel lui-même. Cela fonctionne presque - l'accent est maintenant mis sur le ListBox, mais j'ai encore besoin d'appuyer une fois sur le bouton BAS du clavier avant que l'élément # 0 ait le curseur du clavier. Autrement dit, la mise au point, ou le curseur, est de 1 cran au-dessus article # 0 pour une raison:

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

Répondre

10

Si vous souhaitez mettre au point le premier élément de la zone de liste, vous devez définir le focus sur le premier conteneur ListBoxItem. Par exemple:

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

Il vous reste à faire en sorte que, que le ListBox contrôle a d'abord reçu son Loaded événement. Un certain nombre d'autres événements sont utiles pour gérer les mises à jour liées aux éléments de la zone de liste. Jetez un oeil à la ItemContainerGenerator dans MSDN.

+1

Ça marche! Presque ... Cela fonctionne 100% comme il se doit si j'utilise "Keyboard.Focus (item);" au lieu du FocusManager. Ceci est étrange car MSDN indique que le FocusManager définira le focus logique ET tentera de définir le focus du clavier. Suis-je apprendre la bonne leçon que Keyboard.Focus (item) est ce que je devrais toujours utiliser alors? –

2

La méthode FocusManager.SetFocusedElement donne le focus logique, mais pas le focus du clavier. Vous pouvez utiliser la méthode Keyboard.Focus pour donner le focus du clavier à un élément. Jetez un oeil à this page pour plus de détails sur la gestion de focus dans WPF.

+0

J'ai ajouté Keyboard.Focus (ctrlCountries); et ça ne marche pas. Notez que si j'ajoute un gestionnaire d'événement de clic de bouton qui définit le focus avec le gestionnaire de focus seul, cela fonctionne. –

+1

En d'autres termes, le code suivant ne met pas l'accent sur le premier élément de la liste: private void onLoad (expéditeur d'objet, RoutedEventArgs e) { FocusManager.SetFocusedElement (this, ctrlCountries); Keyboard.Focus (ctrlCountries); } –

+1

Faites-le après que le ListBox soit entièrement chargé (c'est-à-dire lorsque l'événement ctrlCountries.Loaded se produit) –

Questions connexes