问题描述
在WPF程序中,我想获得当前(键盘)焦点,将其存储并稍后重新设置。
为了获得当前的焦点,使用:
DependencyObject focusScope = FocusManager.GetFocusScope(d);
_lastFocus = FocusManager.GetFocusedElement(focusScope);
稍后设置它:
<$如果(_lastFocus!= null)
{
IInputElement setFocus = _lastFocus; p $ p>
_lastFocus = null;
d.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,new ThreadStart(delegate
{
FocusManager.SetFocusedElement(d,setFocus);
}));
}
但是,如果我再试一次,直到我重新创建了我试图设置焦点的冒犯对话框,即使它做了同样的事情(我追踪到获取并设置焦点),它也不起作用。我曾经听说WPF中有两种焦点,我还需要设置其他的东西来获得一致的结果?
你是对的。 WPF具有合理的焦点,您在那里使用和键盘焦点。您可以在MSDN的页面中找到这两者的完整详细信息。 。从该页面:
键盘焦点
逻辑焦点
回到你的问题,你没有使用的另一种焦点是 Keyboard.Focus 。您可以像这样使用它:
Keyboard.Focus(theButtonThatYouWantToFocus);
另外,请注意方法将尝试将 逻辑和键盘焦点设置为被调用的元素。如果键盘焦点和逻辑焦点被设置为这个元素,并且 false ,它将返回 如果只有逻辑焦点被设置为这个元素。
另一种方法可以使用焦点控件是使用 FocusManager.FocusedElement 附加属性。大多数人使用这种静态的,在这种情况下,这只会在视图加载时工作一次:
< Grid FocusManager.FocusedElement ={Binding ElementName = TextBoxToFocus}>
< TextBox Name =TextBoxToFocusText =Focus Me/>
<网格>
然而, 可以在 DataTrigger 并设置它依赖于一个自定义的 bool 属性,在这个例子中, IsFocused
< Style x:Key =FocusableTextBoxStyleTargetType ={x:Type TextBox}> ;
< Style.Triggers>
< DataTrigger Binding ={Binding IsFocused}Value =True>
< Setter Property =FocusManager.FocusedElement
Value ={Binding RelativeSource = {RelativeSource Self}}/>
< / DataTrigger>
< / style>
因此,无论何时将 IsFocused 属性设置为true从视图模型中,应用了 Style 的任何元素都将获得逻辑焦点。现在很清楚, Style 用于 TextBox 控件,但是如果将其更改为 Control 例如。
In a WPF program I want to get the current (keyboard) Focus, store it and re-set it later.
To get the current focus right now I use:
DependencyObject focusScope = FocusManager.GetFocusScope(d); _lastFocus = FocusManager.GetFocusedElement(focusScope);
To set it later I use:
if (_lastFocus != null) { IInputElement setFocus = _lastFocus; _lastFocus = null; d.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(delegate { FocusManager.SetFocusedElement(d, setFocus); })); }
This works once. But if I try again, it does not work until I re-create the offending dialog which I try to set the focus to, even though it does the very same thing (I traced getting and setting the Focus). Instead the main window itself gets the focus.
I once heard there are two kinds of focus in WPF, do I need to set something else, too, to get consistent results?
You are correct. WPF has logical focus, which you are using there and keyboard focus. You can find full details of the two in the Focus Overview page of MSDN. From that page:
Keyboard Focus
Logical Focus
Coming back to your question, the other kind of focus that you are not using is Keyboard.Focus. You can use it like this:
Keyboard.Focus(theButtonThatYouWantToFocus);
Also, note that the UIElement.Focus() method will attempt to set both logical and keyboard focus to the element that it was called on. It will return true if keyboard focus and logical focus were set to this element and false if only logical focus was set to this element.
One other method that you can use to focus controls is to use the FocusManager.FocusedElement Attached Property. Most people use this statically and in this case, this will work just once when the view loads:
<Grid FocusManager.FocusedElement="{Binding ElementName=TextBoxToFocus}"> <TextBox Name="TextBoxToFocus" Text="Focus Me" /> <Grid>
However, it is possible to use this in a DataTrigger and to set it dependent on a custom bool property, in this example, the IsFocused property:
<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>
So whenever I set the IsFocused property to true from the view model, any element with this Style applied will get logical focus. Now clearly, this Style is for the TextBox control, but it will still work if you change it to Control for instance.
这篇关于获取和恢复WPF键盘焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!