2010-01-12 6 views
32

J'ai un TextBox et un ToolBar avec un Button. Si je tape dans le TextBox et que je clique sur le Button, je veux que le TextBox perde Focus pour que la liaison soit mise à jour. Je ne veux pas ajouter un UpdateSourceTrigger=PropertyChanged à mon TextBox. Mais à la place, quand je clique sur le Button, je réinitialise Focus à la fenêtre principale donc quoi que je sois, je perds Focus et met à jour les liaisons.WPF Reset Focus sur le bouton Cliquez sur

J'ai essayé d'ajouter un OnClick au bouton avec ce qui suit, mais il ne semble pas fonctionner:

private void Button_Click(object sender, RoutedEventArgs e) { 
     FocusManager.SetFocusedElement(this, null); 
    } 

Des conseils seraient appréciés.

Merci, Raul

Répondre

25

Le problème est que la barre d'outils met votre bouton dans un autre FocusManager.FocusScope. Cela signifie qu'à la fois le Button et le TextBox peuvent recevoir un focus logique en même temps, chacun dans sa propre portée. C'est normalement une bonne chose, puisque vous ne voulez généralement pas perdre le focus dans votre fenêtre principale lorsque vous sélectionnez des éléments de menu et des boutons ToolBar, mais dans votre cas, cela empêche votre travail de fonctionner. Bien que vous puissiez remplacer la propriété FocusManager.IsFocusScope sur la barre d'outils et obtenir l'effet souhaité, ce n'est probablement pas le meilleur plan, car tous les autres boutons de la barre d'outils dérobent également le focus de votre fenêtre principale.

Au lieu de cela, vous pouvez utiliser l'une des nombreuses solutions faciles:

  • Mettez votre bouton en dehors de la barre d'outils
  • Ajouter un Focusable = contrôle « true » à votre zone principale de la fenêtre et de se concentrer lorsque le bouton est cliqué
  • forcer manuellement la mise à jour en appelant textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
  • temporairement mis Focusable = « true » sur un contrôle dans la fenêtre principale, mise au point placé, puis immédiatement mis Focusable = « false » à nouveau
+0

J'ai essayé un Keyboard.Focus (mainWindow); mais cela ne semble pas changer non plus l'objectif. Il reste sur la zone de texte ou quel élément a été sélectionné. Pour le moment, je force explicitement l'élément à UpdateSource() mais cela ne semble pas être une solution durable à long terme. Je vais essayer d'ajouter un contrôle fantôme pour régler le focus. – HaxElit

+1

'Keyboard.Focus (mainWindow)' ne fonctionnera que si "mainWindow" est Focusable (par défaut il ne l'est pas) et s'il est dans le même 'FocusScope' que le' TextBox'. Essayez de créer un contrôle 'Focusable =" true "' dans le même conteneur que le TextBox et en le concentrant. L'autre contrôle peut être un simple ''. Comme 'Control' n'a pas de template par défaut, il sera invisible. –

+0

Génial! Cela a fonctionné comme un charme. Merci! – HaxElit

32

J'ai rencontré un problème similaire. Je dois décocher une zone de texte lorsque vous appuyez sur Entrée. Je me retrouve avec ce code:

var scope = FocusManager.GetFocusScope(elem); // elem is the UIElement to unfocus 
FocusManager.SetFocusedElement(scope, null); // remove logical focus 
Keyboard.ClearFocus(); // remove keyboard focus 

Je pense qu'il est plus propre que de créer des contrôles fictifs et il est réutilisable. Je ne suis pas confiant avec cette solution cependant. Mais cela semble bien fonctionner.

+3

+1 Fonctionne comme un charme dans les contrôles GotFocus() Event. –

+3

Cela a fonctionné pour moi quand rien d'autre ne forcerait un DatePicker à analyser le texte entré en cliquant sur le bouton Enregistrer dans la barre d'outils. Le code ci-dessous utilise la vue (MVVM) en tant que propriétaire, appelée depuis ViewModel. var t = (DependencyObject) FocusManager.GetFocusedElement (this.Owner); var scope = FocusManager.GetFocusScope (t); FocusManager.SetFocusedElement (scope, null); – Dave

Questions connexes