Wednesday, March 24, 2010

WPF Menu Shortcut and Hot keys

We often use Menu items in our forms having Hot keys and shortcut keys. This is a little bit tricky to use in WPF.

In Windows forms we had an options of adding "&" before the letter we wanted to be the Hot Key. In WPF this is changed to "_".

<Menu DockPanel.Dock="Top">
    <MenuItem Header="_File">        
    </MenuItem>
</Menu>

Running this will display a "_", indicatin a hot key, for "F"

For providing shortcut keys you need to use the InputGestureText property,
<Menu DockPanel.Dock="Top">
    <MenuItem Header="_File">
        <MenuItem Header="Exit" InputGestureText="Ctrl+X">
        </MenuItem>
    </MenuItem>
</Menu>

I have added a submenu item which will be invoked using the Ctrl+X key. Just adding the InputGesture won't actually fire the menu event. We need to also handling the event. This can be done in two ways, either hook to the key strokes to see if "Ctrl+X" is pressed or bind the Command using a Command binding.
This can be done as follows,
<Window.CommandBindings> 
        <CommandBinding Command="{x:Static custom:Window1.MenuRoutedCommand}" 
                    Executed="ExecutedCustomCommand" 
                    CanExecute="CanExecuteCustomCommand" /> 
    </Window.CommandBindings> 

<Menu DockPanel.Dock="Top">
    <MenuItem Header="_File">
        <MenuItem Header="Exit" 
        Command="{x:Static custom:Window1.MenuRoutedCommand}"
        </MenuItem>
    </MenuItem>
</Menu>

code behind,

public static RoutedCommand MenuRoutedCommand = new RoutedCommand();  

public void ExecutedCustomCommand(object sender,    ExecutedRoutedEventArgs e)  
        {  
            MessageBox.Show("Executed");  
        }  
          
        public void CanExecuteCustomCommand(object sender,  
            CanExecuteRoutedEventArgs e)  
        {  
            Control target = e.Source as Control;  
 
            if (target == null)  
            {  
                e.CanExecute = false; 
                return;
            }  
            
              e.CanExecute = true;              
        }  

 public Window1()  
        {  

            InitializeComponent();  
 
           CommandBinding customBinding = new CommandBinding(  
MenuRoutedCommand, ExecutedCustomCommand, CanExecuteCustomCommand);  

            KeyGesture CloseCmdKeyGesture = new KeyGesture(  
    Key.X, ModifierKeys.Control);  
 
            CustomRoutedCommand.InputGestures.Add(CloseCmdKeyGesture);  
}