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

时间:2011-03-29 05:49:20

标签: wpf

我有一个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文件

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 个答案:

答案 0 :(得分:2)

此问题与this完全相同。请在那里看我的答案。

问题是只有在您通过键盘导航时才会出现虚线边框。

答案 1 :(得分:0)

通过编辑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;
            }
        }));
    }
}