Defining MenuItem Shortcuts

H.B. was right... I just wanted to add more precisions.

Remove the Click event on your MenuItem and associate it with a Command instead.

1 - Add/create your commands:

<Window.CommandBindings>
     <CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"/>
     <CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"/>
</Window.CommandBindings>

The commands are refering to the following code:

private void OpenCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    Open();//Implementation of open file
}
private void SaveAsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    SaveAs();//Implementation of saveAs
}

2 - Associate the commands with the wanted keys:

<Window.InputBindings>
    <KeyBinding Key="O" Modifiers="Control" Command="Open"/>
    <KeyBinding Key="S" Modifiers="Control" Command="SaveAs"/>
</Window.InputBindings>

3 - Finally assign the commands with you menu item (InputGestureText is just a decorating text):

<Menu Name="menu1">
    <MenuItem Header="_File">
        <MenuItem Name="menuOpen" Header="_Open..." Command="Open" InputGestureText="Ctrl+O"/>
        <MenuItem Name="menuSaveAs" Header="_Save as..." Command="SaveAs" InputGestureText="Ctrl+S"/>
    </MenuItem>
</Menu>

That way multiple inputs may be associated to the same command.


You need to use KeyBindings (and CommandBindings if you (re)use RoutedCommands such as those found in the ApplicationCommands class) for that in the controls where the shortcuts should work.

e.g.

<Window.CommandBindings>
        <CommandBinding Command="New" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
        <KeyBinding Key="N" Modifiers="Control" Command="New"/>
</Window.InputBindings>

For custom RoutedCommands:

static class CustomCommands
{
    public static RoutedCommand DoStuff = new RoutedCommand();
}

usage:

<Window
    ...
    xmlns:local="clr-namespace:MyNamespace">
        <Window.CommandBindings>
                <CommandBinding Command="local:CustomCommands.DoStuff" Executed="DoStuff_Executed" />
        </Window.CommandBindings>
        <Window.InputBindings>
                <KeyBinding Key="D" Modifiers="Control" Command="local:CustomCommands.DoStuff"/>
        </Window.InputBindings>
    ...
</Window>

(It is often more convenient to implement the ICommand interface rather than using RoutedCommands. You can have a constructor which takes delegates for Execute and CanExecute to easily create commands which do different things, such implementations are often called DelegateCommand or RelayCommand. This way you do not need CommandBindings.)


In my humble opinion is much easier just to use _ at the Header. This will create automatically the desired HotKey.

For example:

<MenuItem Header="_Editar">
<MenuItem Header="_Procurar" Name="MenuProcurar"
          InputGestureText="Ctrl+F"
          Click="MenuProcurar_Click">
    <MenuItem.ToolTip>
        <ToolTip>
            Procurar
        </ToolTip>
    </MenuItem.ToolTip>
</MenuItem>
</MenuItem>