The life of a code monkey

Text

Hidable WPF Menu

** 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:

Posted on Monday, September 26 2011. Tagged with: MenuHideWPFCFirefox MenuCustom Control
10
Notes
  1. dotnetgeek posted this
Got a question or comment? Ask me.
Previous Next