Reputation: 9413
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?
Upvotes: 51
Views: 25794
Reputation: 619
Building off Sam Harwell's excellent answer to take modifiers into account, if you're wanting to go from wpf to winforms and want to include modifier keys you can do this:
Keys formsKey = ...;
System.Windows.Input.Key wpfKey = ...;
wpfKey = KeyInterop.KeyFromVirtualKey((int)formsKey);
formsKey = (Keys)KeyInterop.VirtualKeyFromKey(wpfKey);
if (System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftShift) ||
System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.RightShift))
formsKey |= Keys.Shift;
if (System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftAlt) ||
System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.RightAlt))
formsKey |= Keys.Alt;
if (System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.LeftCtrl) ||
System.Windows.Input.Keyboard.IsKeyDown(System.Windows.Input.Key.RightCtrl))
formsKey |= Keys.Control;
Or if you wanted to go from winforms to wpf:
var isShift = (keys & Keys.LShiftKey) == Keys.LShiftKey || (keys & Keys.RShiftKey) == Keys.RShiftKey;
var isAlt = (keys & Keys.Alt) == Keys.Alt;
var isCtrl = (keys & Keys.LControlKey) == Keys.LControlKey || (keys & Keys.RControlKey) == Keys.RControlKey;
Upvotes: 2
Reputation: 28968
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.
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
}
}
}
Upvotes: 0
Reputation: 477
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;
}
}
Upvotes: 4
Reputation: 776
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);
Upvotes: 2
Reputation: 99869
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.
Upvotes: 80