2010-01-12 9 views
32

Ho una TextBox e un ToolBar con un Button. Se sto scrivendo nel TextBox e fare clic sul Button voglio la TextBox a perdere Focus in modo che il legame viene aggiornato. Non voglio aggiungere uno UpdateSourceTrigger=PropertyChanged al mio TextBox. Ma invece, quando clicco sul Button I ha ripristinato Focus alla finestra principale in modo che cosa mai sono in perde Focus e aggiorna le associazioni.WPF reset concentrarsi sul pulsante Clicca

Ho provato ad aggiungere un OnClick al pulsante con il seguente, ma non sembra funzionare:

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

Eventuali suggerimenti sarebbe apprezzato.

Grazie, Raul

risposta

25

il problema è che la barra degli strumenti mette il pulsante in un diverso FocusManager.FocusScope. Ciò significa che sia il Button e TextBox può ricevere attivo logico allo stesso tempo, ciascuno nel proprio ambito. Normalmente è una buona cosa, dato che di solito non si vuole perdere la messa a fuoco nell'area della finestra principale quando si selezionano le voci di menu e i pulsanti della barra degli strumenti, ma nel tuo caso impedisce ciò che si sta facendo.

Sebbene sia possibile ignorare la proprietà FocusManager.IsFocusScope sulla barra degli strumenti e ottenere l'effetto desiderato, questo non è probabilmente il piano migliore in quanto farebbe sì che tutti gli altri pulsanti della barra degli strumenti rubino lo stato attivo dall'area della finestra principale.

Invece è possibile utilizzare una delle diverse soluzioni facili:

  • Mettere il tasto di fuori della barra degli strumenti
  • Aggiungi un Focusable = controllo "vero" alla vostra zona finestra principale e mettere a fuoco quando il pulsante viene premuto
  • forzare manualmente l'aggiornamento chiamando textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
  • temporaneamente impostare Focusable = "true" su un controllo nella finestra principale, impostare lo stato attivo ad esso, poi subito impostare Focusable = "false" di nuovo
+0

Ho provato un Keyboard.Focus (MainWindow); ma non sembra che stia cambiando il focus. Rimane sulla casella di testo o quale elemento è mai stato selezionato. Per ora imposto esplicitamente l'elemento su UpdateSource() ma non sembra una soluzione sostenibile a lungo termine. Proverò ad aggiungere un controllo fantasma per mettere a fuoco. – HaxElit

+1

'Keyboard.Focus (mainWindow)' funziona solo se "mainWindow" è Focusable (per impostazione predefinita non lo è) e se è nello stesso 'FocusScope' come' TextBox'. Prova a creare un controllo 'Focusable =" true "' nello stesso contenitore del TextBox e focalizzandolo. L'altro controllo può essere un semplice ''. Poiché 'Control' non ha un modello predefinito, sarà invisibile. –

+0

Fantastico! Che ha funzionato come un fascino. Grazie! – HaxElit

32

ho incontrato un problema simile. Ho bisogno di sfocare una casella di testo quando si preme invio. Finisco con questo codice:

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

Penso che sia più pulito rispetto alla creazione di controlli fittizi ed è riutilizzabile. Non sono sicuro di questa soluzione. Ma sembra funzionare bene.

+3

+1 Funziona come un incantesimo nei controlli Evento GotFocus(). –

+3

Questo ha funzionato per me quando nient'altro avrebbe forzato un DataPicker ad analizzare il testo inserito facendo clic sul pulsante Salva nella barra degli strumenti. Il codice seguente utilizza la vista (MVVM) come this.owner, chiamata da ViewModel. var t = (DependencyObject) FocusManager.GetFocusedElement (this.Owner); var scope = FocusManager.GetFocusScope (t); FocusManager.SetFocusedElement (scope, null); – Dave