我有带有工具栏的 WPF 应用程序。在工具栏中,我有一些用户控件作为工具。
我已经为每个控件设置了访问密钥,它工作正常。
问题是:如果我单击用户控件(由按钮和标签组成,我已为按钮设置访问键),则给定任务已完成,但是当我按下任何访问键而不按“Alt”键时,它正在获取选择。
有任何想法吗?
我有带有工具栏的 WPF 应用程序。在工具栏中,我有一些用户控件作为工具。
我已经为每个控件设置了访问密钥,它工作正常。
问题是:如果我单击用户控件(由按钮和标签组成,我已为按钮设置访问键),则给定任务已完成,但是当我按下任何访问键而不按“Alt”键时,它正在获取选择。
有任何想法吗?
显然,这是微软故意改变的。在此处查看 Atanas Koralski 的回答:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14f6f49f-0027-471b-b68c-e7f6ba012012
菜单和工具栏助记符无需按 Alt 键即可工作。我们决定在所有情况下都有统一的行为,因此无需按 Alt 键即可访问键。
我知道这与 Forms 不一致,我们将考虑这个问题并在下一个版本中更改行为。
现在作为一种解决方法,您可以为所有 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的 s 的默认键。如果您不想为这些按钮使用+和+ ,则需要将特殊条件添加到处理程序。Button
IsDefault = true
IsCancel = true
AltEnterAltEsc
从 .Net 4.5 开始,您可以使用CoreCompatibilityPreferences.IsAltKeyRequiredInAccessKeyDefaultScope属性配置此行为。要更改访问键行为,以便它们仅在按下 Alt 时触发,请将其设置为 true。
CoreCompatibilityPreferences.IsAltKeyRequiredInAccessKeyDefaultScope = true;
正如文档所述,这必须在应用程序的早期。设置它会在读取后抛出异常。
如其他答案所述,设置IsAltKeyRequiredInAccessKeyDefaultScope
避免在不按下键的情况下调用访问键的操作Alt。但是,这也可能具有禁用Enter键(用于调用默认操作)和Esc键(用于调用取消操作)的效果。
改用建议的解决方法并测试Key.Enter
andKey.Escape
可以避免此问题。但是,您随后可能会发现菜单项在不按下键的情况下无法通过其访问键选择,Alt如果范围内的按钮使用相同的访问键,这可能是一个问题。
然后,另一种方法是通过检查潜在的可调用AccessText
控件是否在 a 内来处理访问键事件MenuItem
,类似于以下内容:
EventManager.RegisterClassHandler(
typeof(UIElement),
AccessKeyManager.AccessKeyPressedEvent,
new AccessKeyPressedEventHandler(OnAccessKeyPressed));
...
static void OnAccessKeyPressed(object accessKeyTarget, AccessKeyPressedEventArgs e)
{
if (!e.Handled && e.Scope == null &&
(Keyboard.Modifiers & ModifierKeys.Alt) != ModifierKeys.Alt &&
!ShouldElementHandleAccessKeysWhenAltIsNotPressed(accessKeyTarget as UIElement))
{
e.Target = null;
e.Handled = true;
}
}
static bool ShouldElementHandleAccessKeysWhenAltIsNotPressed(UIElement element)
{
if (element == null) return false;
var accessText = element as AccessText;
if (accessText != null && !IsDecendantOfMenuItem(accessText)) return false;
return true;
}
static bool IsDecendantOfMenuItem(DependencyObject element)
{
for (; element != null; element = VisualTreeHelper.GetParent(element))
if (element is MenuItem) return true;
return false;
}