39 votes

Impossible de définir le focus sur un enfant de UserControl

J'ai un UserControl qui contient un TextBox. Lors de ma fenêtre principale de charges je veux mettre l'accent à cette zone de texte j'ai donc ajouté Focusable="True" GotFocus="UC_GotFocus" de la UserControls définition et FocusManager.FocusedElement="{Binding ElementName=login}" de mes fenêtres principales définition. Dans l' UC_GotFocus méthode que j'ai simplement appeler .Focus() sur le contrôle je veux me concentrer sur mais cela ne fonctionne pas.

Tout ce que je dois faire est d'avoir un TextBox en UserControl recevoir le focus lorsque l'application démarre.

Toute aide serait appréciée, merci.

28voto

eesh Points 813

Récemment, j'ai résolu ce problème d'une connexion écran de démarrage est affiché via un storyboard, lorsque la fenêtre principale est chargée pour la première fois.

Je crois qu'il y avait deux clés pour le fixer. L'un était de faire de l'élément contenant l'accent portée. L'autre était de gérer la table de montage séquentiel événement Terminé pour le story-board qui a été déclenchée par la fenêtre en cours de chargement.

Ce storyboard fait le nom d'utilisateur et le mot de passe de la toile visible et puis s'en étant à 100% opaque. L'essentiel est que le nom d'utilisateur de contrôle n'était pas visible jusqu'à ce que le storyboard couru et, par conséquent, que le contrôle ne pouvait pas obtenir de clavier se concentrer jusqu'à ce qu'elle était visible. Ce qui m'a jeté pour un certain temps, qu'elle avait "focus" (c'est à dire l'accent est vrai, mais il s'avère que ce n'était que le focus logique) et je ne savais pas que WPF avait le concept de logique et le focus du clavier jusqu'à ce que la lecture de Kent Boogaart de la réponse et de la recherche à Microsoft WPF texte du lien

Une fois que je n'ai que la solution pour mon problème est simple:

1) Faire de l'élément contenant l'accent portée

<Canvas FocusManager.IsFocusScope="True" Visibility="Collapsed">
	<TextBox x:Name="m_uxUsername" AcceptsTab="False" AcceptsReturn="False">
	</TextBox>
</Canvas>

2) Joindre le formulaire de Gestionnaire d'Événement à la table de montage séquentiel

    <Storyboard x:Key="Splash Screen" Completed="UserNamePassword_Storyboard_Completed">
...
</Storyboard>

et

3) de mettre mon nom d'utilisateur zone de texte pour avoir le focus clavier dans la table de montage terminé gestionnaire d'événement.

void UserNamePassword_Storyboard_Completed(object sender, EventArgs e)
{
 m_uxUsername.Focus();
}

Noter que l'appel de l'élément.Focus() des résultats de l'appel du Clavier.Focus(ce), de sorte que vous n'avez pas besoin d'appeler explicitement. Voir cette question à propos de la différence entre le Clavier.Focus(item) et l'élément.Le Focus.

17voto

fuzquat Points 119

C'est stupide mais ça marche:

Pop un fil qui attend un moment, puis revient et définit le focus que vous voulez. Cela fonctionne même dans le contexte d'un hôte d'élément.

 private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{

 System.Threading.ThreadPool.QueueUserWorkItem(
                   (a) =>
                        {
                            System.Threading.Thread.Sleep(100);
                            someUiElementThatWantsFocus.Dispatcher.Invoke(
                            new Action(() =>
                            {
                                someUiElementThatWantsFocus.Focus();

                            }));
                        }
                   );

}
 

7voto

Vassi Points 472

Tout récemment, j'ai eu une zone de liste qui abritait certains TextBlocks. Je voulais être en mesure de double-cliquer sur le bloc de texte et l'ont se transformer en une zone de texte, puis se concentrer sur et sélectionnez tout le texte afin que l'utilisateur puisse commencer à taper le nouveau nom (similaire à Adobe Couches)

De toute façon, j'ai fait ça avec un événement et cela ne fonctionnait pas. La formule magique pour moi, ici, a été de s'assurer que j'ai mis le cas de traités. Je suppose qu'il a été la mise au point, mais dès que l'événement est passé sur le chemin, c'était la commutation de la logique de se concentrer.

La morale de l'histoire est, assurez-vous de marquer l'événement comme traité, qui pourrait être votre problème.

7voto

David Points 173

"Lors de la définition du focus initial au démarrage de l'application, l'élément à recevoir le focus doit être connecté à un PresentationSource et la propriété doit avoir pour valeur Focusable et IsVisible. L'emplacement recommandé pour définir le focus initial est dans le gestionnaire d'événements chargé" (MSDN)

Ajoutez simplement un gestionnaire d'événements "Loaded" dans le constructeur de votre fenêtre (ou de votre contrôle) et, dans ce gestionnaire d'événements, appelez la méthode Focus () sur le contrôle cible.

     public MyWindow() {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(MyWindow_Loaded);
    }

    void MyWindow_Loaded(object sender, RoutedEventArgs e) {
        textBox.Focus();
    }
 

3voto

Ashley Davis Points 3016

J'ai trouvé une bonne série de billets de blog sur WPF Focus.

http://julmar.com/blog/mark/?p=52

http://julmar.com/blog/mark/?p=51

http://julmar.com/blog/mark/?p=50

Ils sont tous bons à lire, mais la 3ème partie traite spécifiquement de la définition du focus sur un élément d'interface utilisateur dans un UserControl.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X