DataGrid PreviewTextInput事件从输入中删除控制字符

时间:2012-10-11 18:07:00

标签: c# wpf xaml wpf-controls

我有一个带有数据网格的WPF窗口。我试图从Symbol扫描仪中捕获通过虚拟楔形发送的字符串。对于应用程序,它看起来像是键入了字符。该字符串以ASCII 1(SOH)开头。

当窗口具有焦点时,窗口的PreviewTextInput将接收SOH以及所有其他人类可读和非人类可读值。 但是,当数据网格具有焦点时,非人类可读字符就会被删除。

如果我在窗口上有PreviewKeyDown或PreviewKeyUp,则无论焦点是什么,字符都会正确显示。因此,数据网格沿途的某处将其剥离。不幸的是,因为KeyDown / KeyUp没有显示ASCII字符,所以我不能使用这些事件而不必编写某种解析算法。

有人能告诉我我能做些什么来让那些非人类可读的控制字符始终发送到PreviewTextInput?或者如何解析PreviewKeyDown中的所有字符?

编辑:

当窗口具有焦点时:

Window PreviewKeyDown - LeftCtrl
Window PreviewKeyDown - A
Window PreviewTextInput - <SOH>
Window PreviewKeyDown - Oem6
Window PreviewTextInput - ]
Window PreviewKeyDown - LeftShift
Window PreviewKeyDown - C
Window PreviewTextInput - C

当数据网格具有焦点时:

Window PreviewKeyDown - LeftCtrl
DataGrid PreviewKeyDown - LeftCtrl
Window PreviewKeyDown - A
DataGrid PreviewKeyDown - A
Window PreviewKeyDown - Oem6
DataGrid PreviewKeyDown - Oem6
Window PreviewTextInput - ]
Window PreviewKeyDown - LeftShift
DataGrid PreviewKeyDown - LeftShift
Window PreviewKeyDown - C
DataGrid PreviewKeyDown - C
Window PreviewTextInput - C

1 个答案:

答案 0 :(得分:1)

好吧,我知道这可能不是你所期望的,但我有一些为一些Symbol条码扫描器编写软件的经验。在一个应用程序中,我们让用户扫描他们的徽章以验证自己以覆盖某些条件。我们希望用户“扫描”他们的徽章,而不能用键盘输入数字。我记得我们花了很长时间试图找出如何使输入不进入,好像是键盘输入的那样。我相信我们能够从Symbol条形码扫描仪的手册中扫描一些配置代码,将其配置为我们可以打开并处理其输入的USB设备,但我们希望如此。这种方法对我们来说要好得多。

您是否考虑过尝试这样的事情?

MSDN论坛上的这篇文章似乎相关(Converting Key To ASCII

  

条形码阅读器通常可以以两种模式运行。一个是它充当键盘楔形的地方,生成击键就像用户输入代码一样。另一种方法是应用程序直接通过串行端口接收扫描的代码。您已将阅读器切换到可生成适合后一种方式的代码的模式。 Ctrl + B是控制代码,SOH(标题开始)。它用于将程序与阅读器同步,SOH表示扫描的开始,您可以使用它来重置缓冲区索引。

     

您需要将阅读器配置为键盘楔形模式,它不会生成控制字符。如果需要,您仍然可以通过编写KeyDown事件处理程序(用于检测SOH)和KeyPressed事件处理程序来检测扫描代码。避免尝试将您在KeyDown中看到的击键转换为字符,KeyPressed已经为您执行此操作。

我相信这可能会让您转换为ASCII:

[DllImport("user32.dll")]
    static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, byte[] arr, uint uFlags, IntPtr hkl);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetKeyboardState(byte[] lpKeyState);


    private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        byte[] keyboardState = new byte[256];
        int keyCode = KeyInterop.VirtualKeyFromKey(e.Key);
        byte[] arr = new byte[4];
        GetKeyboardState(keyboardState );
        Debug.WriteLineIf(ToAsciiEx((uint)keyCode, 0, keyboardState, arr, 0, IntPtr.Zero) > 0, ASCIIEncoding.ASCII.GetString(arr));
    }