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



我有一个带有数据网格的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

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

你有没有考虑过试试那样的东西?

MSDN论坛上的这篇文章似乎很相关(将密钥转换为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));
}

最新更新