WPF按钮在窗口启动或激活期间拥有键盘焦点(带虚线边框)

3

我有一个WPF窗口,在其中添加了一个按钮。我希望当应用程序启动时(即窗口被激活时),该按钮应该具有键盘焦点,并显示虚线边框。通常情况下,我们使用Tab键导航控件时会看到虚线边框。

我尝试了以下代码,但仍然觉得我漏掉了一些东西。

XAML

<Window x:Class="PropertyChangedTest.TestPropertyChangedWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Activated="Window_Activated">
    <StackPanel Name="justPanel">
        <Button Content="Hello" x:Name="Btn" Height="23" Width="52" Focusable="True" IsDefault="True" Click="Btn_Click"></Button>
    </StackPanel>
</Window>

.cs file

private void Window_Activated(object sender, EventArgs e)
{
    if (!bActivatedOnce)
    {
       bool bVisible = Btn.IsVisible;
       UIElement elementWithFo = Keyboard.Focus(Btn) as UIElement;
       bActivatedOnce = true;             
    }
}  
获得了键盘焦点,但是它周围没有虚线边框。当我按下Alt键时,虚线边框会出现在按钮周围。
2个回答

2
这个问题与这个问题非常相似,请查看我在那里的回答。
问题是只有通过键盘导航时,虚线边框才会出现。

1
通过编辑 KeyboardNavigationEx 文件,来自 ControlzEx,我成功解决了这个问题(全部功劳当然归于punker76)。
只需调用 KeyboardHelper.Focus 方法并传递应该聚焦的 UIElement。以下是在您的情况下的示例:
private void Window_Activated(object sender, EventArgs e)
{
    if (!bActivatedOnce && Btn.IsVisible)
    {
       KeyboardHelper.Focus(Btn);

       bActivatedOnce = true;             
    }
}  

这里是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;
            }
        }));
    }
}

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