【问题标题】:Weird keyboard focus event order奇怪的键盘焦点事件顺序
【发布时间】:2017-11-23 22:58:33
【问题描述】:

奇怪的 WPF 组合框行为:

我刚刚注意到,在 WPF ComboBox 中,当键盘焦点通过 tab 键(从上一个控件中的 tab 键)设置时,TextBoxComboBox ("PART_EditableTextBox") 中是隧道事件的来源OnPreviewGotKeyboardFocus

但出于某种奇怪的原因,如果通过在控件内单击鼠标获得焦点,则OnPreviewGotKeyboardFocus 会被调用两次:第一次,Source 是ComboBox 本身;第二次,Source 又是PART_EditableTextBox

我还注意到,当在 ComboBox 上将 Focusable 设置为 False 时,您仍然可以使用 Tab 键将其聚焦,但不能使用鼠标。

有人知道为什么会出现这种奇怪的行为吗?

【问题讨论】:

    标签: wpf combobox focus


    【解决方案1】:

    来自微软文档。

    KeyboardNavigation 类负责在按下其中一个导航键时实现默认的键盘焦点导航。导航键是:TAB、SHIFT+TAB、CTRL+TAB、CTRL+SHIFT+TAB、UPARROW、DOWNARROW、LEFTARROW 和 RIGHTARROW 键。

    导航容器的导航行为可以通过 设置附加的 KeyboardNavigation 属性 TabNavigation, ControlTabNavigation 和 DirectionalNavigation。这些属性是 类型为 KeyboardNavigationMode,可能的值为 Continue, 本地、包含、循环、一次和无。默认值为 继续,这意味着该元素不是导航容器。

    组合框本身就是一个导航容器。这意味着当您按 Tab 时,PART_EditableTextBox 的容器默认将 KeyBoardNavigationMode 设置为 Continue(这意味着焦点直接转到第一个非容器元素)。相反,click 事件的工作方式不同,因为您没有按下键盘键,因此会覆盖此行为,并且 WPF 将在可视化树中找到的任何元素按顺序启动该事件。这样做是为了确保您可以在焦点到达文本框之前处理此事件以对控件进行操作。此外,您必须考虑这是必要的,因为 WPF 无法确切知道您要单击的内容。这就是为什么他必须按顺序从组合框的每一层引发相同的事件(如果您单击扩展器,焦点不会在 PART_EditableTextBox 内停止)。

    因此,简而言之,如果您要按 TAB,WPF 默认情况下会知道将聚焦的最终元素是组合框内的文本框,这就是组合框本身不需要它来引发事件的原因。另一方面,如果单击组合框,WPF 需要检查哪个元素最终将获得焦点,以及在切换焦点之前是否必须执行一些操作。

    最后关于Focusable属性,控件的这个属性表示该控件是否可以接收焦点,即用户点击该控件后该控件是否可以接收键盘输入。对于旨在接受用户输入的控件,Focusable 通常设置为 true。可以接收键盘焦点的部分是文本框。因此,如果您在组合框内设置 Focusable = false,KeyboardNavigation 类会将焦点放在组合框上,而不是文本框上,因为它无法应用其默认行为

    【讨论】:

    • 感谢您的详细回复。不得不说,这对我来说仍然没有意义,但至少我现在知道它背后的逻辑了。
    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    相关资源
    最近更新 更多