50

I'm developing application in WPF but some components are written using WinForms. I wan't these components to pull key gesture from WPF part and convert them to Keys enum (used in WinForms).

Is there a built in converter for that? (probably not) Do you know "easier than big switch case" method to do that?

Anteru
  • 19,042
  • 12
  • 77
  • 121
Sergej Andrejev
  • 9,091
  • 11
  • 71
  • 108

4 Answers4

77
Keys formsKey = ...;
Key wpfKey = ...;
wpfKey = KeyInterop.KeyFromVirtualKey((int)formsKey);
formsKey = (Keys)KeyInterop.VirtualKeyFromKey(wpfKey);

The KeyInterop class is the "key," plus the fact that the Windows Forms Keys enumeration has the same integer values as the Win 32 virtual key codes.

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
3

Just in case people still encounter the modifier problem 7 years later, here's my solution that worked so far :

public static class KeyEventExts
{
    public static System.Windows.Forms.KeyEventArgs ToWinforms(this System.Windows.Input.KeyEventArgs keyEventArgs)
    {
        // So far this ternary remained pointless, might be useful in some very specific cases though
        var wpfKey = keyEventArgs.Key == System.Windows.Input.Key.System ? keyEventArgs.SystemKey : keyEventArgs.Key;
        var winformModifiers = keyEventArgs.KeyboardDevice.Modifiers.ToWinforms();
        var winformKeys = (System.Windows.Forms.Keys)System.Windows.Input.KeyInterop.VirtualKeyFromKey(wpfKey);
        return new System.Windows.Forms.KeyEventArgs(winformKeys | winformModifiers);
    }

    public static System.Windows.Forms.Keys ToWinforms(this System.Windows.Input.ModifierKeys modifier)
    {
        var retVal = System.Windows.Forms.Keys.None;
        if(modifier.HasFlag(System.Windows.Input.ModifierKeys.Alt))
        {
            retVal |= System.Windows.Forms.Keys.Alt;
        }
        if (modifier.HasFlag(System.Windows.Input.ModifierKeys.Control))
        {
            retVal |= System.Windows.Forms.Keys.Control;
        }
        if (modifier.HasFlag(System.Windows.Input.ModifierKeys.None))
        {
            // Pointless I know
            retVal |= System.Windows.Forms.Keys.None;
        }
        if (modifier.HasFlag(System.Windows.Input.ModifierKeys.Shift))
        {
            retVal |= System.Windows.Forms.Keys.Shift;
        }
        if (modifier.HasFlag(System.Windows.Input.ModifierKeys.Windows))
        {
            // Not supported lel
        }
        return retVal;
    }
}
Uwy
  • 457
  • 7
  • 13
1

If you want to convert modifiers, use the SystemKey if you're looking at a KeyEventArgs:

System.Windows.Input.KeyEventArgs args;
System.Windows.Input.Key wpfKey= args.Key == Key.System ? args.SystemKey : args.Key;
formsKey = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(wpfKey);
Guy Danus
  • 746
  • 2
  • 11
  • 18
0

To convert the WPF Key enumeration to the corresponding WinForms Keys enumeration use the static member TryParse of the Enum class:

Enum.TryParse(wpfKeyEnum.ToString(), out System.Windows.Forms.Keys winFormsKeyEnum)

WPF modifiers (ModifierKeys enumeration) can be converted the same way except the Windows key. In contrast to the Windows.Input.ModifierKeys enumeration of WPF the Windows.Forms.Keys enumeration distinguishes between left and right Windows keys and defines corresponding LWin an RWin fields.

This conversion method works in both directions.

Example

The example converts the Key and ModifierKeys enumerations of a WPF key up event to the corresponding WinForms Keys enumeration.

From Windows.Input.Key To System.Windows.Forms.Keys

private void OnPreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{ 
  // Convert key
  if (Enum.TryParse(e.Key.ToString(), out System.Windows.Forms.Keys winFormsKey))
  {
    MessageBox.Show(winFormsKey + "=" + (int) winFormsKey); // A=65
  }
}

From Windows.Input.ModifierKeys To System.Windows.Forms.Keys

private void OnPreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{ 
  ModifierKeys modifiers = e.KeyboardDevice.Modifiers;

  IEnumerable<ModifierKeys> pressedModifierKeys  = Enum.GetValues(modifiers.GetType())
    .Cast<ModifierKeys>()
    .Where(modifiers.HasFlag);

  // The ModifierKeys enumeration has a FlagsAttribute attribute
  foreach (ModifierKeys modifier in pressedModifierKeys)
  {
    if (Enum.TryParse(modifier.ToString(), out System.Windows.Forms.Keys winFormsModifierKey))
    {
      MessageBox.Show(winFormsModifierKey + "=" + (int) winFormsModifierKey); // Alt=262144
    }
  }
}
BionicCode
  • 1
  • 4
  • 28
  • 44