2013-03-12 34 views
10

有没有什么办法将WPF的KeyEventArgs.Key转换为CharKeyEventArgs.Key to char

我试图用KeyInterop

var x = (Char)KeyInterop.VirtualKeyFromKey(e.Key); 

数字和它工作正常的信件,但对于其他字符没有。 例如对于OemComma它返回'1/4'而不是','。

我需要它来防止用户输入除TextBox以外的任何字符,除了数字和分隔符(即逗号或句点)。

+0

http://stackoverflow.com/questions/5825820/how-to - 如何将字符转换为等价的System.Windows.Input.Key枚举值?](http:// stackoverflow) - 可能的重复字符不同的区域设置键盘在wpf-c – Alex 2013-03-12 11:02:24

+0

.com/questions/544141/how-to-convert-a-character-in-to-equivalent-system-windows-input-key-enum-value) – 2013-03-12 11:04:04

+1

试试'KeyConverter.ConvertToString'而不是 – Rachel 2013-03-12 12:50:56

回答

1

为什么这样的做法?有阻止用户执行此类输入的不同方法。例如,为TextBox.TextChanged -event定义事件处理程序,并在输入不是小数或分隔符时,撤消输入。

private void textChangedEventHandler(object sender, TextChangedEventArgs args){ 
//args contains a property `Changes` where you can see what happened 
//check for invalid characters and revoke them 
} 

请参阅TextChangedEventArgsevent

+3

我用[ PreviewTextInput(HTTP://毫秒dn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SYSTEM.WINDOWS.UIELEMENT.PREVIEWTEXTINPUT);k(VS.XAMLEDITOR);k(SOLUTIONITEMSPROJECT);k(TargetFrameworkMoniker-%22。NETFRAMEWORK%2cVERSION%3dV4.0%22)&RD =真)。不过谢谢。 – 2013-03-13 06:33:23

4

发现这个地方,我忘记了。仍然使用它,不知道它有什么漏洞,但据我所知,它的工作。

public static class KeyEventUtility 
{ 
    // ReSharper disable InconsistentNaming 
    public enum MapType : uint 
    { 
     MAPVK_VK_TO_VSC = 0x0, 
     MAPVK_VSC_TO_VK = 0x1, 
     MAPVK_VK_TO_CHAR = 0x2, 
     MAPVK_VSC_TO_VK_EX = 0x3, 
    } 
    // ReSharper restore InconsistentNaming 

    [DllImport("user32.dll")] 
    public static extern int ToUnicode(
     uint wVirtKey, 
     uint wScanCode, 
     byte[] lpKeyState, 
     [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)] 
     StringBuilder pwszBuff, 
     int cchBuff, 
     uint wFlags); 

    [DllImport("user32.dll")] 
    public static extern bool GetKeyboardState(byte[] lpKeyState); 

    [DllImport("user32.dll")] 
    public static extern uint MapVirtualKey(uint uCode, MapType uMapType); 

    public static char GetCharFromKey(Key key) 
    { 
     char ch = ' '; 

     int virtualKey = KeyInterop.VirtualKeyFromKey(key); 
     var keyboardState = new byte[256]; 
     GetKeyboardState(keyboardState); 

     uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC); 
     var stringBuilder = new StringBuilder(2); 

     int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0); 
     switch (result) 
     { 
     case -1: 
      break; 
     case 0: 
      break; 
     case 1: 
      { 
       ch = stringBuilder[0]; 
       break; 
      } 
     default: 
      { 
       ch = stringBuilder[0]; 
       break; 
      } 
     } 
     return ch; 
    } 
} 
+0

对于此代码中的错误,请参阅此处的注释:http://stackoverflow.com/a/5826175/187650 – juFo 2016-11-15 11:30:56

0

我的第一个建议是使用PreviewTextInput和使用TextCompositionEventArgs。 然而这'吃'空间字符。 对于这种“space'发出看:

另一个解决方案是使用KeyConverterKEYUP事件:

KeyConverter kc = new KeyConverter(); 
    var str = kc.ConvertToString(e.Key); 

对于WPFhttps://msdn.microsoft.com/en-us/library/system.windows.input.keyconverter(v=vs.110).aspx 对于的WinFormshttps://msdn.microsoft.com/en-us/library/system.windows.forms.keysconverter.aspx

注意KeyConverter会给你字符串 “空间”,而不是 “”。 (同样按下ESC键时为 “ESC”

另一个WPF溶液在KEYUP事件中使用这样的:

((char)KeyInterop.VirtualKeyFromKey(e.Key))