关于wpf:调用CheckBox.Focus()时如何使CheckBox焦点边框出现?

How to make CheckBox focus border appear when calling CheckBox.Focus()?

当用户在CheckBox中使用制表符使其具有焦点时,CheckBox周围将出现一个虚线边框,以表明其具有焦点。

当CheckBox通过调用myCheckBox.Focus()的代码获得焦点时,不会出现这样的指示符(即使按下空格键可以切换状态)。

当我以编程方式使CheckBox聚焦时,如何显示CheckBox聚焦边框?


仅在通过键盘(Tab键)导航时才有意显示边框。关于此主题的MSDN页面具有更多详细信息:

Focus visual styles act only when the
focus action was initiated by the
keyboard. Any mouse action or
programmatic focus change disables the
mode for focus visual styles.

如果要显示边框,可以在IsFocused-属性上使用"触发器"进行一些视觉更改(尽管您不能以此设置边框),或者如果您实际上想要边框,则必须创建自己的ControlTemplate。

SO上还有一个线程在某个相关主题上,该主题的建议是模拟按键,但我建议不要针对您的问题使用此解决方案。


通过编辑ControlzEx中的KeyboardNavigationEx文件,我设法解决了这个问题(一如既往,这全归功于punker76)。

只需调用KeyboardHelper.Focus方法并传递应重点关注的UIElement(例如KeyboardHelper.Focus(myCheckBox))

这是KeyboardHelper类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public sealed class KeyboardHelper
{
    private static KeyboardHelper _Instance;

    private readonly PropertyInfo _AlwaysShowFocusVisual;
    private readonly MethodInfo _ShowFocusVisual;

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static KeyboardHelper()
    {
    }

    private KeyboardHelper()
    {
        var type = typeof(KeyboardNavigation);

        _AlwaysShowFocusVisual = type.GetProperty("AlwaysShowFocusVisual", BindingFlags.NonPublic | BindingFlags.Static);
        _ShowFocusVisual = type.GetMethod("ShowFocusVisual", BindingFlags.NonPublic | BindingFlags.Static);
    }

    internal static KeyboardHelper Instance => _Instance ?? (_Instance = new KeyboardHelper());

    internal void ShowFocusVisualInternal()
    {
        _ShowFocusVisual.Invoke(null, null);
    }

    internal bool AlwaysShowFocusVisualInternal
    {
        get { return (bool)_AlwaysShowFocusVisual.GetValue(null, null); }
        set { _AlwaysShowFocusVisual.SetValue(null, value, null); }
    }

    public static void Focus(UIElement element)
    {
        element?.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
        {
            var keybHack = KeyboardHelper.Instance;
            var oldValue = keybHack.AlwaysShowFocusVisualInternal;

            keybHack.AlwaysShowFocusVisualInternal = true;

            try
            {
                Keyboard.Focus(element);
                keybHack.ShowFocusVisualInternal();
            }
            finally
            {
               keybHack.AlwaysShowFocusVisualInternal = oldValue;
            }
        }));
    }
}

1
2
3
4
5
6
7
8
9
10
11
'initially set chkCheckBox.Appearance = 1

'on Got Focus set appearance = 0 - Flat
Private Sub chkCheckBox_GotFocus()
  chkCheckBox.Appearance = 0
End Sub

'on Lost Focus set appearance = 1 - 3D
Private Sub chkCheckBox_LostFocus()
  chkCheckBox.Appearance = 1
End Sub