2012-12-19 11 views
15

Sto sbattendo la testa su quello che sembra un problema così semplice da risolvere in wpf ma devo ancora scoprire perché non riesco a far funzionare la mia app secondo il mio Piano.Keyboard.Focus non funziona sulla casella di testo in WPF

Ho una piccola casella di ricerca che compare nella mia applicazione wpf quando l'utente preme ctrl + f. Tutto quello che voglio è che il caret lampeggi all'interno della casella di testo della casella di ricerca, pronto a prendere qualsiasi input dell'utente senza che l'utente debba cliccarci sopra. Ecco il codice xaml per la casella di testo che è visibile, abilitata, hit testabile, tabstopable e focusable.

<TextBox x:Name="SearchCriteriaTextBox" Text="{Binding SearchCriteria}" Focusable="True" IsEnabled="True" IsTabStop="True" IsHitTestVisible="True" Style="{DynamicResource SearchTextBoxStyle}" Grid.Column="1" Margin="5,10,0,5" /> 

nel codice dietro, ho questo metodo chiamato quando la visibilità della casella di ricerca è interessato. la casella di ricerca viene caricata all'inizio dell'applicazione.

/// <summary> 
    /// Handles events triggered from focusing on this view. 
    /// </summary> 
    /// <param name="sender">The sender.</param> 
    /// <param name="dependencyPropertyChangedEventArgs">The key event args.</param> 
    private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 
    { 
     if (!((bool) dependencyPropertyChangedEventArgs.NewValue)) 
     { 
      return; 
     } 

     SearchCriteriaTextBox.Focus(); 
     Keyboard.Focus(SearchCriteriaTextBox); 
     SearchCriteriaTextBox.Select(0, 0); 

     if (SearchCriteriaTextBox.Text.Length > 0) 
     { 
      SearchCriteriaTextBox.SelectAll(); 
     } 
    } 

Il problema è, il codice viene chiamato, componente diventa IsFocused = vero, ma non guadagna attivo della tastiera. Mi manca qualcosa? A meno che un altro controllo non si mantenga ferocemente sul focus della tastiera che sono abbastanza sicuro di non aver programmato, perché questo pezzo di codice piuttosto semplice non funzionerebbe correttamente.

+2

Provare a farlo dopo l'evento Loaded. –

+1

Immagino che un altro controllo diventi attivo dopo che questo metodo è stato chiamato. Forse dovresti concentrarti su un altro evento. – Ramin

+0

@HighCore Ho una domanda: l'evento Loaded si attiva ogni volta che cambia la visibilità? – Ramin

risposta

50

Come soluzione alternativa, si potrebbe provare a utilizzare il Dispatcher per impostare la messa a fuoco in un secondo DispatcherPriority, come ad esempio Input

Dispatcher.BeginInvoke(DispatcherPriority.Input, 
    new Action(delegate() { 
     SearchCriteriaTextBox.Focus();   // Set Logical Focus 
     Keyboard.Focus(SearchCriteriaTextBox); // Set Keyboard Focus 
    })); 

Dalla descrizione del problema, sembra che non si dispone di messa a fuoco della tastiera impostato. WPF può avere più Focus Scopes, quindi più elementi possono avere Logical Focus (IsFocused = true), tuttavia solo un elemento può avere Keyboard Focus e riceverà input da tastiera.

Il codice che è stato pubblicato deve impostare correttamente lo stato attivo, quindi è necessario che in seguito si verifichi qualcosa per spostare Keyboard Focus fuori dal proprio TextBox. Impostando lo stato attivo a una priorità successiva del dispatcher, ti assicurerai che l'impostazione di messa a fuoco della tastiera su SearchCriteriaTextBox venga eseguita per ultima.

+1

Appena scoperto che, stava per pubblicare la mia risposta, grazie a Rachel funziona perfettamente in un ambiente multi thread. EDIT: puoi chiamare Dispatcher.BeginInvoke (DispatcherPriority.Input, new ThreadStart (() => SearchCriteriaTextBox.Focus())); allo stesso risultato, senza dover richiamare la casella di testo focus – legrandviking

+0

Questo funziona per me: MessageBox.Show ("foo"); myTextBox.Select (0, myTextBox.Text.Length); myTextBox.Messa a fuoco(); – Krafty

+0

Qualcuno ha una spiegazione per questo problema? –

0

Se aiuta qualcuno, ho riscontrato questo problema e la mia applicazione aveva una finestra principale con più controlli utente posizionati in griglie separate con un bind di visibilità. Poiché le griglie erano presenti quando è stata creata l'applicazione, il metodo .Focus() chiamato Loaded o Constructor veniva chiamato al momento della compilazione, non al momento della visibilità.

In ogni caso l'ho risolto chiamando .Focus() sull'evento MouseEnter della griglia. Funziona bene per me.

Problemi correlati