Try the following solution - a better and more compact solution in WPF. This also works if your control has not the focus or if you programatically enter the menu mode via InputManager.Current.PushMenuMode(menuSite);
(see the end of the post).
Add the following code to your window or user control which contains your menu myMenu
- for example at the end of your constructor:
this.myMenu.Height = 0; // Initially hide the menu
InputManager.Current.EnterMenuMode += this.InputManager_MenuModeToggled;
InputManager.Current.LeaveMenuMode += this.InputManager_MenuModeToggled;
Then implement the event handler:
private void InputManager_MenuModeToggled(object sender, EventArgs e)
{
if (!InputManager.Current.IsInMenuMode)
this.myMenu.Height = 0; // 0 to hide the menu
else
this.myMenu.Height = double.NaN; // NaN to reset the height (auto height)
}
Consider the following notes:
- Set
Height=0
instead of Visiblity
to Collapsed
/Hidden
, because if the menu is invisible then the menu mode may not will be entered when Alt key will be pressed.
- The menu must contains at least ony item, otherwise the menu mode may not will be entered when Alt key will be pressed.
- In my opinion this solution also applies to MVVM applications, because its UI logic and not View Model logic.
Tested with target framework .NET Framework 4.5
within a WPF app on a Windows 10 machine.
Added:
If you want to enter the menu mode programmatically you can call the menu mode via: InputManager.Current.PushMenuMode(menuSite);
However I had the issue that if I call the method PushMenuMode
that after then the menu mode never will be leaved. So I fixed this with following solution:
PresentationSource source = PresentationSource.FromVisual(this);
InputManager.Current.PushMenuMode(menuSite: source);
this.Menu.Focus();
RoutedEventHandler lostFocus = null;
lostFocus = (s, args) =>
{
InputManager.Current.PopMenuMode(menuSite: source);
this.Menu.LostFocus -= lostFocus;
};
this.Menu.LostFocus += lostFocus;