2013-10-10 66 views
5

在WPF程序中,我想獲取當前(鍵盤)焦點,將其存儲並稍後重新設置。獲取並恢復WPF鍵盤焦點

要獲得目前的工作重點,現在我使用:

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

要設置後來我用:

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

只能用一次。但是如果我再試一次,它將不起作用,直到我重新創建我試圖設置焦點的有問題的對話框,即使它做了同樣的事情(我追蹤到了並設置焦點)。主窗口本身就是焦點所在。

我曾經聽說WPF中有兩種焦點,我是否還需要設置其他的東西來獲得一致的結果?

回答

18

你是對的。 WPF具有邏輯焦點,您在那裏使用和鍵盤焦點。您可以在MSDN的Focus Overview頁面找到這兩者的完整詳細信息。從這個頁面:

鍵盤焦點

鍵盤焦點是指當前正在接收鍵盤輸入的元素。整個桌面上只能有一個鍵盤焦點的元素。在WPF中,具有鍵盤焦點的元素將IsKeyboardFocused設置爲true。 Keyboard類上的靜態屬性FocusedElement獲取當前具有鍵盤焦點的元素。

爲了使元素獲得鍵盤焦點,必須將基本元素上的Focusable和IsVisible屬性設置爲true。某些類(例如面板基類)的Focusable默認設置爲false;因此,如果您希望這樣的元素能夠獲得鍵盤焦點,則必須將Focusable設置爲true。

鍵盤焦點可以通過用戶與UI的交互獲得,例如對元素進行標籤或在某些元素上單擊鼠標。鍵盤焦點也可以通過使用Keyboard類上的Focus方法以編程方式獲得。 Focus方法嘗試給出指定元素的鍵盤焦點。返回的元素是具有鍵盤焦點的元素,如果舊焦點對象或新焦點對象阻止該請求,則該元素可能與請求不同。

邏輯焦點

邏輯焦點指FocusManager.FocusedElement在聚焦範圍。焦點範圍是一個跟蹤其範圍內的FocusedElement的元素。當鍵盤焦點離開焦點範圍時,焦點元素將失去鍵盤焦點,但會保留邏輯焦點。當鍵盤焦點返回焦點範圍時,焦點元素將獲得鍵盤焦點。這允許在多個焦點範圍之間改變鍵盤焦點,但是確保當焦點返回焦點範圍時,焦點範圍中的焦點元素重新獲得鍵盤焦點。

可以有多個元素在應用程序中具有邏輯焦點,但在特定焦點範圍內可能只有一個元素具有邏輯焦點。

具有鍵盤焦點的元素對於它所屬的焦點範圍具有邏輯焦點。


現在回到你的問題,你是不是使用其他種類的焦點是Keyboard.Focus。您可以使用它像這樣:

Keyboard.Focus(theButtonThatYouWantToFocus); 

而且,請注意UIElement.Focus()方法將嘗試邏輯鍵盤焦點設置到元素,它被稱爲上。如果僅將邏輯焦點設置爲此元素,如果將鍵盤焦點和邏輯焦點設置爲此元素和false,它將返回true


,你可以用它來集中控制的另外一個方法是使用FocusManager.FocusedElementAttached Property。大多數人靜態使用,在這種情況下,當視圖加載這將工作只是一次:

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

然而,可能在DataTrigger利用這一點,並把它依賴於定製bool屬性在這個例子中,IsFocused屬性:

<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> 

所以每當我從視圖模型,這個Style應用將獲得邏輯焦點任何元素設置IsFocused屬性爲true。現在很清楚,Style用於控制TextBox,但如果將其更改爲Control,它仍然可以工作。

+0

太棒了!我在設置邏輯焦點時添加了Keyboard.Focus(setFocus),現在它可以工作,非常感謝! – Sam

+0

通過使用[FocusManager.IsFocusScope](http://msdn.microsoft.com/zh-cn/library/system.windows.input.focusmanager.isfocusscope),您實際上可以完全消除捕獲/恢復代碼。 ASPX)。 – Olly

+0

*某些類(例如Panel基類)的Focusable默認設置爲false *。這是我的關鍵。 – dotNET

0

首先,您應該使用Keyboard.Clear(),稍後再寫Keyboard.Focus("Your Input element")

Keyboard.Clear()明確您的焦點參考。之後,您可以專注於界面的任何元素。