2013-10-10 3 views
5

In einem WPF-Programm möchte ich den aktuellen Fokus (Focus) abrufen, speichern und später neu einstellen.Holen und Wiederherstellen WPF Tastaturfokus

Um jetzt den aktuellen Fokus zu erhalten Ich verwende:

DependencyObject focusScope = FocusManager.GetFocusScope(d); 
_lastFocus = FocusManager.GetFocusedElement(focusScope); 

es einzustellen später ich benutze:

if (_lastFocus != null) 
{ 
    IInputElement setFocus = _lastFocus; 
    _lastFocus = null; 
    d.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(delegate 
    { 
    FocusManager.SetFocusedElement(d, setFocus); 
    })); 
} 

Dieses Mal funktioniert. Aber wenn ich es noch einmal versuche, funktioniert es nicht, bis ich den beleidigenden Dialog neu erstellt habe, auf den ich den Fokus richten möchte, obwohl es genau das Gleiche tut (ich habe versucht, den Fokus zu bekommen und einzustellen). Stattdessen erhält das Hauptfenster selbst den Fokus.

Ich habe einmal gehört, dass es zwei Arten von Fokus in WPF gibt, muss ich auch etwas anderes setzen, um konsistente Ergebnisse zu erhalten?

Antwort

18

Sie haben Recht. WPF hat den logischen Fokus, den Sie dort verwenden, und den Tastaturfokus. Sie können alle Details der beiden auf der Focus Overview Seite von MSDN finden. Von dieser Seite:

Tastaturfokus

Tastaturfokus bezieht sich auf das Element, das zur Zeit Tastatureingabe empfängt. Auf dem gesamten Desktop kann nur ein Element mit Tastaturfokus vorhanden sein. In WPF wird IsKeyboardFocused für das Element mit Tastaturfokus auf True gesetzt. Die statische Eigenschaft FocusedElement für die Keyboard-Klasse ruft das Element ab, das derzeit über den Tastaturfokus verfügt.

Damit ein Element den Tastaturfokus erhalten kann, müssen die Eigenschaften Focusable und IsVisible auf den Basiselementen auf true festgelegt werden. Einige Klassen, z. B. die Panel-Basisklasse, haben Focusable standardmäßig auf false festgelegt. Daher müssen Sie Focusable auf True setzen, wenn ein solches Element den Tastaturfokus erhalten soll.

Der Tastaturfokus kann durch Benutzerinteraktion mit der Benutzeroberfläche abgerufen werden, z. B. das Einfassen eines Elements oder das Klicken auf bestimmte Elemente. Der Tastaturfokus kann auch programmgesteuert mithilfe der Focus-Methode für die Keyboard-Klasse abgerufen werden. Die Focus-Methode versucht, dem angegebenen Element den Tastaturfokus zuzuweisen. Das zurückgegebene Element ist das Element mit Tastaturfokus, das möglicherweise ein anderes Element als angefordert ist, wenn entweder das alte oder das neue Fokusobjekt die Anforderung blockieren.

Logical Fokus

Logical Fokus bezieht sich auf die FocusManager.FocusedElement in einen Fokusbereich. Ein Fokusbereich ist ein Element, das das FocusedElement in seinem Bereich verfolgt. Wenn der Fokus der Tastatur einen Fokusbereich verlässt, verliert das fokussierte Element den Tastaturfokus, behält jedoch den logischen Fokus bei. Wenn der Tastaturfokus zum Fokusbereich zurückkehrt, erhält das fokussierte Element den Tastaturfokus. Dies ermöglicht das Ändern des Tastaturfokus zwischen mehreren Fokusbereichen, stellt jedoch sicher, dass das fokussierte Element im Fokusbereich den Tastaturfokus wiedererlangt, wenn der Fokus zum Fokusbereich zurückkehrt.

Es kann mehrere Elemente geben, die in einer Anwendung den logischen Fokus haben, aber möglicherweise gibt es nur ein Element, das in einem bestimmten Fokusbereich einen logischen Fokus hat.

Ein Element mit Tastaturfokus hat einen logischen Fokus für den Fokusbereich, zu dem es gehört.


kommend auf Ihre Frage zurück, die andere Art von Fokus, die Sie nicht ist Keyboard.Focus verwenden. Sie können es wie folgt verwenden:

Keyboard.Focus(theButtonThatYouWantToFocus); 

Beachten Sie auch, dass die UIElement.Focus() Methode versuchen, sowohl logische und Tastaturfokus auf das Element zu setzen, dass es auf genannt. Es wird truezurückgegeben, wenn Tastaturfokus und logischer Fokus auf dieses Element gesetzt wurden und falsewenn nur logischer Fokus auf dieses Element gesetzt wurde.


Eine andere Methode, die Sie Kontrollen konzentrieren verwenden können, ist die FocusManager.FocusedElementAttached Property zu verwenden. Die meisten Leute benutzen diese statisch und in diesem Fall wird dies nur einmal funktionieren, wenn die Sicht Lasten:

<Grid FocusManager.FocusedElement="{Binding ElementName=TextBoxToFocus}"> 
    <TextBox Name="TextBoxToFocus" Text="Focus Me" /> 
<Grid> 

aber es möglich ist, dies in einem DataTrigger zu verwenden und sie auf einer benutzerdefinierten bool Eigenschaft abhängig zu setzen , in diesem Beispiel die IsFocused Eigenschaft:

<Style x:Key="FocusableTextBoxStyle" TargetType="{x:Type TextBox}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsFocused}" Value="True"> 
      <Setter Property="FocusManager.FocusedElement" 
       Value="{Binding RelativeSource={RelativeSource Self}}" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Also, wenn ich die IsFocused Eigenschaft auf true aus dem view-Modell, jedes Element mit diesen Style erhält angewendet logischen Fokus. Jetzt ist dies eindeutig Style für die TextBox Kontrolle, aber es funktioniert immer noch, wenn Sie es zum Beispiel zu Control ändern.

+0

Großartig! Ich habe Keyboard.Focus (setFocus) hinzugefügt, als ich den logischen Fokus einstellte und jetzt funktioniert es, vielen Dank! – Sam

+0

Sie können Ihren Capture/Restore-Code mit [FocusManager.IsFocusScope] (http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.isfocusscope) möglicherweise vollständig beseitigen. aspx). – Olly

+0

* Bei einigen Klassen, z. B. der Panel-Basisklasse, ist Focusable standardmäßig auf false gesetzt *. Das war der Schlüssel für mich. – dotNET

0

Zuerst sollten Sie Keyboard.Clear() verwenden und später Keyboard.Focus("Your Input element") schreiben.

Keyboard.Clear() löschen Sie Ihre Fokusreferenz. Danach können Sie sich auf das Element Ihrer Oberfläche konzentrieren.