获取和恢复WPF键盘焦点

时间:2013-10-10 07:50:08

标签: wpf focus

在WPF程序中,我想获取当前(键盘)Focus,存储它并稍后重新设置。

为了获得当前的焦点,我使用:

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中有两种焦点,我是否还需要设置其他内容以获得一致的结果?

2 个答案:

答案 0 :(得分:21)

你是对的。 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()方法将尝试将逻辑键盘焦点设置为调用它的元素。如果键盘焦点和逻辑焦点设置为此元素,则会返回true ,如果仅将逻辑焦点设置为此元素,则会返回false 。< / p>


可用于集中控件的另一种方法是使用FocusManager.FocusedElement Attached 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>

因此,每当我从视图模型中将IsFocused属性设置为true时,应用了此Style的任何元素都将获得逻辑焦点。现在很明显,Style适用于TextBox控件,但如果您将其更改为Control,它仍然有效。

答案 1 :(得分:0)

首先,您应该使用Keyboard.Clear()并稍后再写Keyboard.Focus("Your Input element")

Keyboard.Clear()清除您的焦点参考。之后,您可以专注于界面的任何元素。