diff --git a/Perspex.Controls/Menu.cs b/Perspex.Controls/Menu.cs
index 5eeb375525..f831a70f3e 100644
--- a/Perspex.Controls/Menu.cs
+++ b/Perspex.Controls/Menu.cs
@@ -13,11 +13,12 @@ namespace Perspex.Controls
using Perspex.LogicalTree;
using Perspex.Rendering;
using Perspex.Interactivity;
+ using Perspex.Controls.Primitives;
///
/// A top-level menu control.
///
- public class Menu : ItemsControl, IFocusScope, IMainMenu
+ public class Menu : SelectingItemsControl, IFocusScope, IMainMenu
{
///
/// Defines the default items panel used by a .
@@ -55,6 +56,29 @@ namespace Perspex.Controls
private set { this.SetValue(IsOpenProperty, value); }
}
+ ///
+ /// Closes the menu.
+ ///
+ public void CloseMenu()
+ {
+ foreach (MenuItem i in this.GetLogicalChildren())
+ {
+ i.IsSubMenuOpen = false;
+ }
+
+ this.IsOpen = false;
+ this.SelectedIndex = -1;
+ }
+
+ ///
+ /// Opens the menu in response to the Alt/F10 key.
+ ///
+ public void OpenMenu()
+ {
+ this.SelectedIndex = 0;
+ ((IInputElement)this.SelectedItem)?.Focus();
+ }
+
///
/// Called when the is attached to the visual tree.
///
@@ -75,6 +99,13 @@ namespace Perspex.Controls
this.subscription = new CompositeDisposable(
pointerPress,
Disposable.Create(() => topLevel.Deactivated -= this.Deactivated));
+
+ var inputRoot = root as IInputRoot;
+
+ if (inputRoot != null && inputRoot.AccessKeyHandler != null)
+ {
+ inputRoot.AccessKeyHandler.MainMenu = this;
+ }
}
///
@@ -87,6 +118,20 @@ namespace Perspex.Controls
this.subscription.Dispose();
}
+ ///
+ /// Called when a key is pressed within the menu.
+ ///
+ /// The event args.
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+
+ if (this.IsOpen && e.Key == Key.Escape)
+ {
+ this.CloseMenu();
+ }
+ }
+
///
/// Called when a submenu opens somewhere in the menu.
///
@@ -109,19 +154,6 @@ namespace Perspex.Controls
this.IsOpen = true;
}
- ///
- /// Closes the menu.
- ///
- private void CloseMenu()
- {
- foreach (MenuItem i in this.GetLogicalChildren())
- {
- i.IsSubMenuOpen = false;
- }
-
- this.IsOpen = false;
- }
-
///
/// Called when the top-level window is deactivated.
///
@@ -129,7 +161,7 @@ namespace Perspex.Controls
/// The event args.
private void Deactivated(object sender, EventArgs e)
{
- this.CloseMenu();
+ //this.CloseMenu();
}
///
diff --git a/Perspex.Controls/MenuItem.cs b/Perspex.Controls/MenuItem.cs
index 616d52b71e..069ca74cbe 100644
--- a/Perspex.Controls/MenuItem.cs
+++ b/Perspex.Controls/MenuItem.cs
@@ -15,11 +15,13 @@ namespace Perspex.Controls
using Perspex.Rendering;
using Perspex.Controls.Templates;
using Perspex.Controls.Presenters;
+ using Perspex.VisualTree;
+
///
/// A menu item control.
///
- public class MenuItem : HeaderedItemsControl
+ public class MenuItem : SelectingItemsControl, ISelectable
{
///
/// Defines the property.
@@ -33,12 +35,24 @@ namespace Perspex.Controls
public static readonly PerspexProperty