Search code examples
c#.netwinformsshortcutmainmenu

Convert user input String to MenuItem.Shortcut


I have written an extension framework for an app, and I would like the user to be able to setup keyboard shortcuts for their extension to be run.

When I add the MenuItem to the MainMenu Control at runtime, I would like to be able to use Crtl+N, for example, to run the extension instead of having to click the MenuItem with the mouse or keyboard.

But the problem is I don't know how to convert the user's string value to a MenuItem.Shortcut.

For example, here is the keyboard shortcut the user has chosen "Ctrl+N"

How do I convert this somehow to a MenuItem.Shortcut? I cannot find anything on MSDN about this. I've read the documentation.


Solution

  • You could parse the user input as string with something like:

    var shortcut = Enum.Parse(typeof(Shortcut), "CtrlN");
    

    but I suggest you don't do that. You force the user to enter something like CtrlShiftF10, with the correct case, otherwise the input fails validation.
    A dedicated interface, similar to the Shortcut converter shown in the PropertyGrid would be better, so you don't force the User to guess what to write and avoid typos.

    But you can also assign the Shortcut enumerator's values (which represent a combination of Keys) to, e.g., the DataSource of a ComboBox, so you let the User select one of the entries.

    For example, using the MainMenu Component (deprecated in .Net Core 3.1+), get the values of the Shortcut enumerator, then set the Shortcut Property of a MenuItem:

    someComboBox.DataSource = Enum.GetValues(typeof(Shortcut));
    someComboBox.SelectionChangeCommitted += (s, e) => 
        { var selectedShortcut = (Shortcut)(s as ComboBox).SelectedItem; };
    

    Using a MenuStrip Control, you have to cast SelectedItem to Keys instead. The Shortcut enumerator is available in .Net, so the code remains the same (except the cast):

    // [...]
    someComboBox.SelectionChangeCommitted += (s, e) => 
        { var selectedKeys = (Keys)(s as ComboBox).SelectedItem; };