I cannot find a way of accessing the items in a menu when using the keyboard only. If I first use the mouse to open one of the menu items I can then proceed to navigate with the keyboard. It is just that initial step when moving focus from RadMenu and into the menu items that is missing. I have tried using the space bar, the enter key, the arrow keys, the page down keys etc., but nothing seems to work.
I did come up with a workaround, a behavior that attaches to RadMenu and listens to the enter key and the down-arrow key. When either of these keys are pressed I invoke the automation peer of the first available menu item. It is a little crude, but seems to work ok. I'm attaching the code below.
/Henrik
I did come up with a workaround, a behavior that attaches to RadMenu and listens to the enter key and the down-arrow key. When either of these keys are pressed I invoke the automation peer of the first available menu item. It is a little crude, but seems to work ok. I'm attaching the code below.
/Henrik
using System; |
using System.Net; |
using System.Windows; |
using System.Windows.Controls; |
using System.Windows.Documents; |
using System.Windows.Ink; |
using System.Windows.Input; |
using System.Windows.Media; |
using System.Windows.Media.Animation; |
using System.Windows.Shapes; |
using System.Windows.Interactivity; |
using System.Windows.Data; |
using Telerik.Windows.Controls; |
using System.Windows.Automation.Peers; |
using System.Windows.Automation.Provider; |
namespace GLS.Gui.Helper.Behaviors |
{ |
/// <summary> |
/// When attached to a RadMenu, the menu will respond to the Enter and Down keys. |
/// If one of the keys are pressed when the menu is in focus, the first item in the menu will expand. |
/// </summary> |
public class ExpandFirstItemOnKeyboardNav : Behavior<RadMenu> |
{ |
/// <summary> |
/// Called after the behavior is attached to an AssociatedObject. |
/// </summary> |
/// <remarks>Override this to hook up functionality to the AssociatedObject.</remarks> |
protected override void OnAttached() |
{ |
this.AssociatedObject.KeyDown += AssociatedObject_KeyDown; |
base.OnAttached(); |
} |
void AssociatedObject_KeyDown(object sender, KeyEventArgs e) |
{ |
if ((e.Key == Key.Down || e.Key == Key.Enter) && AssociatedObject.Items.Count > 0) |
{ |
var item = (AssociatedObject.Items[0] as RadMenuItem); |
// Create an automation peer |
var peer = new RadMenuItemAutomationPeer(item); |
// Create an InvokeProvider |
var invokeProvider = peer.GetPattern(PatternInterface.ExpandCollapse) as IInvokeProvider; |
// Invoke |
invokeProvider.Invoke(); |
} |
} |
/// <summary> |
/// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. |
/// </summary> |
/// <remarks>Override this to unhook functionality from the AssociatedObject.</remarks> |
protected override void OnDetaching() |
{ |
this.AssociatedObject.KeyDown -= AssociatedObject_KeyDown; |
base.OnDetaching(); |
} |
} |
} |