KeyEventArgs.Key to char

max*_*sen 13 c# wpf textbox keyeventargs

有没有办法将WPF转换KeyEventArgs.KeyChar

我试着用KeyInterop:

var x = (Char)KeyInterop.VirtualKeyFromKey(e.Key);
Run Code Online (Sandbox Code Playgroud)

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

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

ken*_*nny 5

更新:以下评论找到了最初的http://stackoverflow.com/a/5826175/187650

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


juF*_*uFo 5

我的第一个建议是使用PreviewTextInput和使用TextCompositionEventArgs。然而,这“吃掉”了空格字符。对于这个“空间”问题,请参见:

另一种解决方案是在KeyUp事件中使用KeyConverter

  KeyConverter kc = new KeyConverter();
  var str = kc.ConvertToString(e.Key);
Run Code Online (Sandbox Code Playgroud)

对于WPFhttps : //msdn.microsoft.com/en-us/library/system.windows.input.keyconverter ( v = vs.110).aspx对于Winformshttps : //msdn.microsoft.com/en-我们/图书馆/system.windows.forms.keysconverter.aspx

请注意,KeyConverter 将为您提供字符串“Space”而不是“”。(按 Esc 键时与“Esc”相同。

另一个 WPF 解决方案是在KeyUp事件中使用它:

((char)KeyInterop.VirtualKeyFromKey(e.Key))
Run Code Online (Sandbox Code Playgroud)


bas*_*h.d 2

为什么要采取这样的做法?有多种方法可以阻止用户执行此类输入。例如,为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
}
Run Code Online (Sandbox Code Playgroud)

请参阅TextChangedEventArgs事件

  • 我用 [PreviewTextInput](http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SYSTEM.WINDOWS.UIELMENT.PREVIEWTEXTINPUT);k(VS.XAMLEDITOR) 解决了这个问题;k(SOLUTIONITEMSPROJECT);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22)&rd=true)。但无论如何还是谢谢你。 (4认同)