即使我们没有按';Alt';输入WPF

即使我们没有按';Alt';输入WPF,wpf,wpf-controls,access-keys,Wpf,Wpf Controls,Access Keys,我有WPF应用程序,它有工具栏。在工具栏中,我有一些用户控件作为工具 我已经为每个控件设置了访问键,它工作正常 问题是:如果我单击一个用户控件(由按钮和标签组成,我已经为按钮设置了访问键),给定的任务就完成了,但是当我在没有按“Alt”键的情况下按任何访问键时,它就被选中了 有什么想法吗?显然,这是微软有意做出的改变。请参见Atanas Koralski的回答: 菜单和工具栏助记符在不按Alt键的情况下工作。我们决定 我们在所有情况下都有统一的行为,所以访问密钥工作 不按Alt键 我理解这与形

我有WPF应用程序,它有工具栏。在工具栏中,我有一些用户控件作为工具

我已经为每个控件设置了访问键,它工作正常

问题是:如果我单击一个用户控件(由按钮和标签组成,我已经为按钮设置了访问键),给定的任务就完成了,但是当我在没有按“Alt”键的情况下按任何访问键时,它就被选中了


有什么想法吗?

显然,这是微软有意做出的改变。请参见Atanas Koralski的回答:

菜单和工具栏助记符在不按Alt键的情况下工作。我们决定 我们在所有情况下都有统一的行为,所以访问密钥工作 不按Alt键

我理解这与形式不一致,我们将 考虑这个问题并改变下一个版本的行为。

现在,作为一种解决方法,您可以为所有 AccessKeyPressed事件,如果未按Alt键,则处理该事件 按

EventManager.RegisterClassHandler(typeof(UIElement),
AccessKeyManager.AccessKeyPressedEvent,
new AccessKeyPressedEventHandler(OnAccessKeyPressed));

private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
{
    if (!e.Handled && e.Scope == null && (e.Target == null || e.Target == label))
    {
        // If Alt key is not pressed - handle the event
        if ((Keyboard.Modifiers & ModifierKeys.Alt) != ModifierKeys.Alt)
        {
            e.Target = null;
            e.Handled = true;
        }
    }
}
另见mfc2wpf的回复:

我用过上面的方法,效果很好。然而,这阻止了违约 Enter和ESC的操作。因此,我将以下内容插入到 方法

if (Keyboard.IsKeyDown(Key.Enter) || Keyboard.IsKeyDown(Key.Escape)) return;

访问键包括Enter和Esc,它们是具有
IsDefault=true
IsCancel=true
按钮的默认键。如果不希望这些按钮需要Alt+Enter和Alt+Esc,则需要将特殊条件添加到处理程序。

从.Net 4.5开始,您可以使用属性配置此行为。要更改访问键的行为,使其仅在按下Alt时触发,请将其设置为true

CoreCompatibilityPreferences.IsAltKeyRequiredInAccessKeyDefaultScope = true;

正如文档所述,这必须在应用程序的早期进行。设置它将在读取后引发异常。

如其他答案中所述,设置
IsAltKeyRequiredInAccessKeyDefaultScope
可避免在不按Alt键的情况下调用访问键的操作。但是,这也会导致禁用Enter键(用于调用默认操作)和Esc键(用于调用取消操作)

使用建议的解决方法,并测试
Key.Enter
Key.Escape
,可以避免此问题。但是,您可能会发现,如果不按Alt键,菜单项的访问键就无法选择,如果作用域中的按钮使用相同的访问键,则可能会出现问题

另一种方法是通过检查潜在可调用的
AccessText
控件是否在
MenuItem
中来处理访问密钥事件,具体如下:

EventManager.RegisterClassHandler(
  typeof(UIElement),
  AccessKeyManager.AccessKeyPressedEvent,
  new AccessKeyPressedEventHandler(OnAccessKeyPressed));

private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
{
    if (!e.Handled && e.Scope == null && (e.Target == null || e.Target == label))
    {
        // If Alt key is not pressed - handle the event
        if ((Keyboard.Modifiers & ModifierKeys.Alt) != ModifierKeys.Alt)
        {
            e.Target = null;
            e.Handled = true;
        }
    }
}

我必须注意,将IsAltKeyRequiredInAccessKeyDefaultScope设置为true也会在未按下ALT时禁用标有IsDefault和IsCancel的按钮的ENTER和ESC。