2013-10-10 3 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로 설정해야합니다. Panel 기본 클래스와 같은 일부 클래스에는 기본적으로 Focusable이 false로 설정되어 있습니다. 그러므로 이러한 요소가 키보드 포커스를 얻을 수있게하려면 Focusable을 true로 설정해야합니다.

요소로 이동하거나 특정 요소에서 마우스를 클릭하는 등 UI와의 사용자 상호 작용을 통해 키보드 포커스를 얻을 수 있습니다. 키보드 포커스는 Keyboard 클래스의 Focus 메서드를 사용하여 프로그래밍 방식으로 얻을 수도 있습니다. Focus 메서드는 지정된 요소 키보드 포커스를 지정하려고 시도합니다. 반환 된 요소는 이전 또는 새 포커스 객체가 요청을 차단 한 경우 요청한 요소와 다른 요소 일 수있는 키보드 포커스가있는 요소입니다.

논리적 포커스

논리적 포커스는 포커스 범위에 FocusManager.FocusedElement을 말한다. 포커스 범위는 해당 범위 내에서 FocusedElement를 추적하는 요소입니다. 키보드 포커스가 포커스 범위를 벗어나면 포커스가있는 요소는 키보드 포커스를 잃지 만 논리적 포커스는 유지됩니다. 키보드 포커스가 포커스 범위로 돌아 오면 포커스가있는 요소는 키보드 포커스를 얻습니다. 이렇게하면 여러 포커스 범위 사이에서 키보드 포커스를 변경할 수 있지만 포커스 범위로 포커스가 되돌아 가면 포커스 범위의 포커스 요소가 키보드 포커스를 다시 확보합니다.

응용 프로그램에 논리적 포커스가있는 요소가 여러 개있을 수 있지만 특정 포커스 범위에 논리적 포커스가있는 요소는 하나만있을 수 있습니다.

키보드 포커스가있는 요소에는 해당 포커스 범위에 대한 논리적 포커스가 있습니다.


질문으로 돌아오고, 사용하지 않는 초점이 다른 종류의 Keyboard.Focus입니다. 이처럼 사용할 수 있습니다 또한


Keyboard.Focus(theButtonThatYouWantToFocus); 
UIElement.Focus() 방법이에 호출되었음을 요소에 논리적 키보드 포커스를 모두 설정하려고 않습니다. 논리적 포커스 만이 요소으로 설정된 경우 키보드 포커스 및 논리적 포커스가이 요소 및 false 으로 설정된 경우 true을 반환합니다.


당신이 컨트롤을 집중하는 데 사용할 수있는 또 다른 방법은 FocusManager.FocusedElementAttached Property을 사용하는 것입니다. 대부분의 사람들은 정적이 사용하고보기를로드 할 때이 경우,이 한 번만 작동합니다, DataTrigger이를 사용하고 사용자 정의 bool 특성에 의존 설정 가능하지만

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

입니다 이 예에서 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있는 모든 요소에서 true로 IsFocused 속성을 설정합니다. 이제 분명히이 StyleTextBox 컨트롤이지만, 예를 들어 Control으로 변경하면 여전히 작동합니다.

+0

대단원! 논리적 초점을 설정할 때 Keyboard.Focus (setFocus)를 추가했는데 이제는 작동합니다. – Sam

+0

실제로 [FocusManager.IsFocusScope] (http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.isfocusscope)를 사용하여 캡처/복원 코드를 완전히 제거 할 수 있습니다. aspx). – Olly

+0

* Panel 기본 클래스와 같은 일부 클래스에는 기본적으로 Focusable이 false로 설정되어 있습니다. 이것이 나를위한 열쇠였습니다. – dotNET

0

먼저 Keyboard.Clear()을 사용하고 나중에 Keyboard.Focus("Your Input element")으로 작성해야합니다.

Keyboard.Clear() 초점 참조를 지 웁니다. 그런 다음 인터페이스의 요소에 초점을 맞출 수 있습니다.