WPF - 为什么 Keyboard.Focus() 不起作用?

发布于 2024-10-15 06:00:31 字数 301 浏览 2 评论 0原文

TabItem 控件上有一个 TextBox 项 (MyTextBox)。我的代码如下所示:

MyTextBox.Focus();
Keyboard.Focus(MyTextBox);

当我通过调试器运行此代码时,执行行后我会看到以下内容:

MyTextBox.IsFocused = true
MyTextBox.IsKeyboardFocused = false

谁能告诉我为什么文本框没有接收键盘焦点?它只是一个启用的标准 TextBox 控件。

have a TextBox item (MyTextBox) on a TabItem control. I have code that looks as follows:

MyTextBox.Focus();
Keyboard.Focus(MyTextBox);

When I run this code through the debugger I see the following after the lines are executed:

MyTextBox.IsFocused = true
MyTextBox.IsKeyboardFocused = false

Can anyone tell me why the textbox isn't receiving keyboard focus? It's just a standard TextBox control that is enabled.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

不弃不离 2024-10-22 06:00:31

当您尝试将 Focus 设置为除了我们同事上面列举的元素之外的元素时,您还必须知道 WPF 不允许跨线程操作。

在某些情况下,不会像 Focus 方法调用情况那样引发此异常。我为解决此问题所做的工作是在操作中调用所有涉及键盘焦点的代码。

此操作在控制调度程序内部运行,以确保我的代码不会从 UI 线程之外的另一个线程执行(例如计时器事件或从另一个线程引发的事件):

[UIElement].Dispatcher.BeginInvoke(
      new Action(
         delegate{
             /// put your Focus code here
         }
      )
);

When you try to set Focus to an element besides the things enumerated above by our coleague, you must also know that WPF does not allow cross threaded operations.

In some cases this exception is not raised like in the Focus method call case. What I've done to fix this issue is to call all the code that involves Keyboards focus in an action.

This action is ran inside the control dispatcher to make sure that my code is not being executed from another thread than the UI thread (e.g. timer event or an event raised from another thread):

[UIElement].Dispatcher.BeginInvoke(
      new Action(
         delegate{
             /// put your Focus code here
         }
      )
);
与君绝 2024-10-22 06:00:31

MyTextBox.IsKeyboardFocused 为 false,因为您正在调试器下查看它,并且键盘焦点可能在您的 Visual Studio 中...尝试在没有断点的情况下调试焦点(例如 Debug.Write或跟踪制动点)以查看运行时 MyTextBox.IsKeyboardFocused 的实际值。

另请注意,Focus() 方法返回布尔值,指示焦点是否已成功设置。在你的情况下它会返回 False 吗?如果是,我建议进入 Focus() 方法以找出问题所在。

MyTextBox.IsKeyboardFocused is false because you are looking at it under debugger and the keyboard focus is probably in your Visual Studio... Try debugging focus without breakpoints (e.g. Debug.Write or trace brakepoints) to see actual values of MyTextBox.IsKeyboardFocused in runtime.

Also notice that Focus() method returns boolean value that indicates whether focus was successfully set. Does it return False in your case? If yes, I would suggest stepping into Focus() method in order to find out what is wrong.

债姬 2024-10-22 06:00:31

3 个重要属性必须为 trueIsVisible="True"Focusable="True"IsEnabled="True"

要获得焦点,Focusable 和 IsEnabled 都必须为 true。

http://msdn.microsoft.com/en-us /library/system.windows.uielement.focus.aspx

3 important properties must be true: IsVisible="True", Focusable="True". IsEnabled="True".

To be focusable, Focusable and IsEnabled must both be true.

http://msdn.microsoft.com/en-us/library/system.windows.uielement.focus.aspx

婴鹅 2024-10-22 06:00:31

无论调试器告诉您什么,此处接受的答案都不能解决文本框未获得焦点的问题。如果您有并且可以写入文本框,那么您就拥有以键盘为中心的文本框。

我发现这里解决了问题(并且实际上获得了焦点,而不仅仅是设置值,使其看起来像调试器中的焦点),它非常接近巴甫洛夫的答案,但带有“焦点代码”: Keyboard.Focus 不适用于 WPF 中的文本框

The accepted answer here does not solve the problem of textboxes who dont gain focus, no matter what the debugger tells you. If you have and can write to your textbox, then you have it keyboard-focused.

I found this here solving the problem (and actually gaining focus, not just settings the values so it looks like focus in the debugger), it comes very close to Pavlov's answer but with the "Focus code" : Keyboard.Focus does not work on text box in WPF

浊酒尽余欢 2024-10-22 06:00:31

前两行代码的执行位置很重要。

如果它们位于与用户按下按键、使用鼠标、更改控件的可见性或以其他方式采取可能影响焦点的操作相关的事件处理程序中,我发现手动调用 Focus() 通常不起作用。

我的理论是,WPF 在内部的运行方式如下:

  1. 用户或代码采取可能对焦点产生影响的操作,例如,在以前没有可聚焦控件的焦点范围内启用 TextBox 控件。
  2. WPF 通知各种事件处理程序,包括您调用 Focus() 的事件处理程序。
  3. WPF 根据步骤 1 中的状态更改更新焦点。这会覆盖您在步骤 2 中所做的任何操作。

这就是此答案的原因建议在排队回调中调用 Focus(),该回调将在第 3 步之后执行。

附注:您不需要同时调用 UIElement.FocusKeyboard.Focus 自第一个包含第二个(至少如果您信任 Microsoft 文档)。

总之,将前两行代码替换为:

// using System.Windows.Threading;
Dispatcher.BeginInvoke(DispatcherPriority.Input, MyTextBox.Focus);

It's important where your first two lines of code are executed.

If they are in an event handler that relates to the user pressing a key, using the mouse, altering the visibility of a control, or otherwise taking an action that might have an impact on focus, I find manually calling Focus() often doesn't work.

My theory is that internally, WPF operates as follows:

  1. User or code takes action which could have an impact on focus, e.g. a TextBox control becomes enabled inside a focus scope which previously had no focusable control.
  2. WPF notifies various event handlers, including yours which calls Focus().
  3. WPF updates focus based on the state changes in step 1. This overrides whatever you did in step 2.

That is why this answer suggests to call your Focus() in a queued callback which will be executed after step 3.

Side note: you don't need to call both UIElement.Focus and Keyboard.Focus since the first includes the second (at least if you trust the Microsoft docs).

In conclusion, replace your first two lines of code with this:

// using System.Windows.Threading;
Dispatcher.BeginInvoke(DispatcherPriority.Input, MyTextBox.Focus);
属性 2024-10-22 06:00:31

这对我有用(必须执行 UpdateLayout,否则 Focus() 在从脚本更改选项卡后不会立即工作)

tabControl.SelectedIndex = 2;
this.UpdateLayout();
txtMyTextBox.Focus();

This worked for me (had to do UpdateLayout, otherwise Focus() didn't work immediately after changing tab from script)

tabControl.SelectedIndex = 2;
this.UpdateLayout();
txtMyTextBox.Focus();
归途 2024-10-22 06:00:31

我也有同样的问题。我只是将所有焦点代码移至元素的可见事件处理程序中。下面的代码为我解决了这个问题:

textBox.IsVisibleChanged += (s, e) => {
    // any focus code you need. E.g.
    Keyboard.Focus(textBox);
    textBox.Focus();
    textBox.SelectAll();

};

I had the same problem. I simply moved all my focus code to the visible-event-handler of the element. The following code solves the problem for me:

textBox.IsVisibleChanged += (s, e) => {
    // any focus code you need. E.g.
    Keyboard.Focus(textBox);
    textBox.Focus();
    textBox.SelectAll();

};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文