WPF:如何以编程方式从TextBox中删除焦点

jps*_*res 87 wpf textbox focus

我想在我的WPF中添加一个简单的(至少我认为是)行为TextBox.

当用户按Escape时,我希望TextBox他正在编辑以获得用户开始编辑时所具有的文本,并且我想从中移除焦点TextBox.

我没有任何问题为编辑开头的值设置文本.

问题是要删除元素的焦点.我不想把焦点转移到任何其他组件,我只是想TextBox失去焦点.我是否必须有一个不可见的元素来设置焦点,以便我TextBox可以失去焦点?

LPL*_*LPL 136

在.NET Framework 4中 Keyboard.ClearFocus();

  • 这并不总是清晰的焦点:我有一个问题,当我在某个地方点击后从代码隐藏运行`Keyboard.ClearFocus()`时,ListBox中的AutoCompleteTextBox不会失去焦点. (9认同)
  • @Grault这只清除键盘焦点,而不是逻辑焦点(这是对`GotFocus`事件的触发).在您的程序中始终存在逻辑焦点.在清除键盘焦点之前,使用`LostKeyboardFocus`事件或将焦点移动到另一个元素(它会随之移动逻辑焦点). (6认同)
  • `ClearFocus`导致`GotFocus`不会为最近聚焦的控件触发,而它仍然会触发其他控件.例如,对于我的自定义屏幕键盘来说,这是一个大问题.它确实导致插入符号消失,这可能是"键盘焦点"所需要的.也许我对"鼠标焦点"这样的东西更感兴趣. (3认同)
  • 谢谢Grault,我遇到了同样的问题。我想出的最好的办法是将焦点转移到其他的控件上(other.Focus())。 (2认同)

dec*_*jau 52

我一直在使用的代码:

// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)textBox.Parent;
while (parent != null && parent is IInputElement && !((IInputElement)parent).Focusable)
{
    parent = (FrameworkElement)parent.Parent;
}

DependencyObject scope = FocusManager.GetFocusScope(textBox);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
Run Code Online (Sandbox Code Playgroud)

  • @patrick,**哪些**意外的副作用?你能举出相关的例子吗? (4认同)
  • 这段代码很棒,Keyboard.ClearFocus()有一些意想不到的副作用 (2认同)
  • 这是一个很好的解决方案。我也遇到了 Keyboard.ClearFocus() 问题。在模态窗口内的 TextBox 上运行 ClearFocus() 时,它会导致 TextBox 和 Window 都失去焦点。这意味着 KeyDown 事件不再进入窗口。通过改为更改它以便将焦点更改为父级(可能是窗口),未来的 KeyDown 事件不会丢失。在我的实际示例中,我让 Window 寻找“Key.Escape”并调用 Close()。如果您在任何地方运行 ClearFocus(),这将停止工作。 (2认同)

Sup*_*Oli 18

派对有点晚了,但这对我很有帮助.

从.Net 3.0开始,FrameworkElement有一个MoveFocus函数可以帮助我.


Jul*_*uez 9

您可以将焦点设置为可聚焦的祖先.即使文本框位于同一模板内没有可聚焦祖先的模板内,此代码也能正常工作:

DependencyObject ancestor = textbox.Parent;
while (ancestor != null)
{
    var element = ancestor as UIElement;
    if (element != null && element.Focusable)
    {
        element.Focus();
        break;
    }

    ancestor = VisualTreeHelper.GetParent(ancestor);
}
Run Code Online (Sandbox Code Playgroud)


bit*_*onk 6

AFAIK,无法完全消除焦点.窗口中的某些内容始终具有焦点.


Cyc*_*one 6

由于以上答案均不适用于我,并且接受的答案仅对键盘焦点有效,因此我采用以下方法:

// Kill logical focus
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
// Kill keyboard focus
Keyboard.ClearFocus();
Run Code Online (Sandbox Code Playgroud)

同时杀死逻辑和键盘焦点。

  • 非常感谢,我尝试了所有其他将焦点转移到其他地方的方法,你的方法有效。 (2认同)

Bri*_* Ng 5

对我来说,这相当棘手,尤其是与 LostFocus 绑定一起使用时。但是,我的解决方法是添加一个空标签并关注它。

<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />
Run Code Online (Sandbox Code Playgroud)

...

OnKeyDown(object sender, RoutedEventArgs e)
{
  //if is Esc
  ResetFocusArea.Focus();
}
Run Code Online (Sandbox Code Playgroud)