-
dotnetgeek posted this
** ATTENTION THERE IS A BUG IN THIS CODE SEE PART 2 FOR THE FIX **
Recently I needed to create a menu on a form that would remain hidden until the user pressed the Alt key. Similar behavior to the menu in Firefox 6.x.
To accomplish this I elected to make a custom control that extends System.Windows.Control.Menu. The code for it is pretty trivial.
using System.Windows.Controls; using System.Windows; namespace AutoHideMenuBar { public class HidableMenu : Menu { public HidableMenu() { Height = 0; } protected override void OnGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) { if (itemIsChild(e.NewFocus as DependencyObject)) { Height = double.NaN; } base.OnGotKeyboardFocus(e); } protected override void OnLostKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) { if (itemIsChild(e.NewFocus as DependencyObject) == false) { Height = 0; } base.OnLostKeyboardFocus(e); } private bool itemIsChild(DependencyObject dependancyObject) { if (ReferenceEquals(dependancyObject, null)) return false; if (ReferenceEquals(dependancyObject, this)) return true; return itemIsChild(LogicalTreeHelper.GetParent(dependancyObject)); } } }
The key parts here are the two method overrides. When each are called the object gaining focus is checked to see if it is a child of the HideableMenu. Settings the Height of a menu to double.NaN will let the menu auto size its height. This means that for menus that define a height (not common, and not needed for my purposes) this code will need modifications.
Finally here is the code in action.
<Window x:Class="AutoHideMenuBar.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="201" Width="259" xmlns:local="clr-namespace:AutoHideMenuBar"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <local:HidableMenu VerticalAlignment="Top"> <MenuItem Header="_File"> <MenuItem Header="_New"/> <MenuItem Header="_Open"/> <Separator /> <MenuItem Header="E_xit"/> </MenuItem> <MenuItem Header="_Help"> <MenuItem Header="_About" /> </MenuItem> </local:HidableMenu> <StackPanel Grid.Row="1"> <TextBlock Text="Type in the box" Margin="5"/> <TextBox Margin="5"/> <Button Content="OK" Margin="10"/> </StackPanel> </Grid> </Window>
With the menu bar hidden:

And after pressing the Alt key:
