WPF - 为什么 Keyboard.Focus() 不起作用?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当您尝试将 Focus 设置为除了我们同事上面列举的元素之外的元素时,您还必须知道 WPF 不允许跨线程操作。
在某些情况下,不会像 Focus 方法调用情况那样引发此异常。我为解决此问题所做的工作是在操作中调用所有涉及键盘焦点的代码。
此操作在控制调度程序内部运行,以确保我的代码不会从 UI 线程之外的另一个线程执行(例如计时器事件或从另一个线程引发的事件):
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):
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 ofMyTextBox.IsKeyboardFocused
in runtime.Also notice that
Focus()
method returns boolean value that indicates whether focus was successfully set. Does it returnFalse
in your case? If yes, I would suggest stepping intoFocus()
method in order to find out what is wrong.3 个重要属性必须为
true
:IsVisible="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
无论调试器告诉您什么,此处接受的答案都不能解决文本框未获得焦点的问题。如果您有并且可以写入文本框,那么您就拥有以键盘为中心的文本框。
我发现这里解决了问题(并且实际上获得了焦点,而不仅仅是设置值,使其看起来像调试器中的焦点),它非常接近巴甫洛夫的答案,但带有“焦点代码”: 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
前两行代码的执行位置很重要。
如果它们位于与用户按下按键、使用鼠标、更改控件的可见性或以其他方式采取可能影响焦点的操作相关的事件处理程序中,我发现手动调用 Focus() 通常不起作用。
我的理论是,WPF 在内部的运行方式如下:
Focus()
的事件处理程序。这就是此答案的原因建议在排队回调中调用
Focus()
,该回调将在第 3 步之后执行。附注:您不需要同时调用 UIElement.Focus 和 Keyboard.Focus 自第一个包含第二个(至少如果您信任 Microsoft 文档)。
总之,将前两行代码替换为:
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:
Focus()
.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:
这对我有用(必须执行 UpdateLayout,否则 Focus() 在从脚本更改选项卡后不会立即工作)
This worked for me (had to do UpdateLayout, otherwise Focus() didn't work immediately after changing tab from script)
我也有同样的问题。我只是将所有焦点代码移至元素的可见事件处理程序中。下面的代码为我解决了这个问题:
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: