如何在调用CheckBox.Focus()时使CheckBox的焦点边框出现?

4

当用户通过Tab键将焦点放在复选框上时,会出现一个虚线边框以指示该复选框具有焦点。

当代码调用myCheckBox.Focus()使复选框获得焦点时,不会出现此类指示器(尽管按空格键可以切换状态)。

我如何在程序化地将焦点集中在复选框上时使复选框的焦点边框出现?

3个回答

9
只有在使用键盘(Tab键)导航时才会故意显示边框。关于此主题的MSDN页面有更多细节:

焦点可视化样式仅在通过键盘启动焦点操作时起作用。任何鼠标操作或编程焦点更改都会禁用焦点可视化样式模式。

如果您想显示边框,可以使用IsFocused-属性上的触发器进行一些视觉更改(尽管无法使用此方法设置边框),或者如果您实际上需要边框,则必须创建自己的ControlTemplate。
这里还有一个SO上的线程,涉及到一个类似的主题,建议模拟按键,但我建议不要使用此解决方案来解决您的问题。

如何在不必搞乱样式的情况下,直观地显示对话框中哪个按钮是默认按钮呢? - Noman_1

2
通过编辑 ControlzExKeyboardNavigationEx 文件,我成功解决了这个问题(所有功劳都归功于 punker76)。
只需调用 KeyboardHelper.Focus 方法并传递应该聚焦的 UIElement (例如 KeyboardHelper.Focus(myCheckBox))即可。
下面是 KeyboardHelper 类的代码:
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;
            }
        }));
    }
}

0
'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

1
WPF中的CheckBox没有“Appearance”属性。这个答案是针对WinForms吗? - Greg Sansom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接