如何防止输入控件从 TextCompositionManager 窃取空格字符?
与此问题相关(但不是欺骗!):Help with the WPF TextCompositionManager events
使用 TextCompositionManager 时,我遇到一个问题,如果输入控件(例如 TextBox)具有焦点,则 TextBox 将在我有机会执行操作之前“窃取”空格字符它。
例如,我们有以下代码:
public Window1()
{
TextCompositionManager.AddPreviewTextInputStartHandler
(this, PreviewTextInputStartHandler);
}
private void PreviewTextInputHandler(object sender, TextCompositionEventArgs e)
{
CaptureTextBlock.Text += e.Text;
e.Handled = true;
}
其中 Window1 如下所示:
<!--standard window crap above here-->
<StackPanel>
<TextBlock Name="CaptureTextBlock" />
<TextBox Name="ThievingBastard" />
</StackPanel>
<!-- snip -->
现在,如果我运行此应用程序并立即键入“我讨厌小偷混蛋”,则 TextBlock 将包含文本“我讨厌小偷混蛋”,并且文本框将为空。
但是,如果我聚焦文本框(即文本框具有键盘焦点),则在输入上述行后,文本块将包含文本“Ihaetthifyingbastards”,并且文本框将包含文本“”(3 个空格)。
我有两个问题:
1) 我可以仅使用 TextCompositionManager 提供的功能来防止这种情况发生吗?
2)如果没有,我到底应该在哪里插入文本输入堆栈,以便我可以完全控制我的WPF应用程序中的文本输入(甚至考虑p/调用的缺点)(你只是想关于它,添加了负分)?
更新
我正在使用一种巧妙的解决方法,仅处理来自空间的 InputManager 的隧道 KeyDown 事件。 这种方法非常笨拙,效率低下,而且基本上很臭。 仍在寻找更好的方法。
Related (but not a dupe!) to this question: Help with the WPF TextCompositionManager events
When using the TextCompositionManager I'm having an issue where, if an input control such as the TextBox has focus, the TextBox will "steal" the space character before I can get a chance to act on it.
For example, we have the following code:
public Window1()
{
TextCompositionManager.AddPreviewTextInputStartHandler
(this, PreviewTextInputStartHandler);
}
private void PreviewTextInputHandler(object sender, TextCompositionEventArgs e)
{
CaptureTextBlock.Text += e.Text;
e.Handled = true;
}
where Window1 looks like:
<!--standard window crap above here-->
<StackPanel>
<TextBlock Name="CaptureTextBlock" />
<TextBox Name="ThievingBastard" />
</StackPanel>
<!-- snip -->
Now, if I run this application and immediately type "I haet thieving bastards", the TextBlock will contain the text "I haet thieving bastards" and the textbox will be empty.
If, however, I focus the textbox (i.e., textbox has keyboard focus), after typing the above line the textblock will contain the text "Ihaetthievingbastards" and the textbox will contain the text " " (3 spaces).
I have two questions:
1) Can I prevent this from happening with just the facilities provided by the TextCompositionManager?
2) If not, where the hell do I plug into the text input stack so that I can fully control text input within my WPF application (negative points for even thinking about p/invoking) (you just thought about it, negative points added)?
Update
I'm using a hacky workaround where I handle the tunneling KeyDown event from the InputManager for spaces only. This method is very awkward, inefficient and basically stinks. Still looking for a better way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了他人的利益,我的黑客代码。
我的特定应用程序正在等待读卡器刷卡。 以下内容存在于监视刷卡的对象的构造函数中(这是一个业余项目;大多数评论咒骂已被编辑掉):
两种方法:
当有人按下某个键(或将击键发送到系统)时,PreNotifyInput事件发生。 在这种情况下,我确定它是否是一个特殊的键(对我来说,我必须担心空格,但其他键显然需要特别注意)。 如果它是一个特殊键,我将“处理”该事件,停止对该击键的所有进一步处理。 然后,我调用传入空格的内部处理方法(或我刚刚截获的任何特殊键)。
所有其他键均由 PreviewTextInputHandler 方法处理。
这段代码去掉了很多东西。 确定滑动事件何时发生、确定滑动何时完成、防护措施(超时,以防我永远不会停止捕获滑动)等都被删除。 您如何执行此操作将取决于您的代码要求。
For the benefit of others, my hacky code.
My particular app is waiting for a card swipe from a card reader. The following lives in the constructor of the object that watches for a card swipe (this is a side project; most comment cursing edited out):
The two methods:
When somebody presses a key (or a keystroke is sent to the system) the PreNotifyInput event fires. In this case, I determine if it is a special key (for me I have to worry about the space, but other keys apparently need special attention). If it is a special key, I "handle" the event, stopping all further processing of this keystroke. I then call my internal processing method passing in the space (or whatever special key I just intercepted).
All other keys are handled by the PreviewTextInputHandler method.
This code has a lot of stuff stripped out of it. Determining when a swipe event has happened, determining when the swipe has completed, safeguards (timeouts in case I never stop capturing a swipe), etc is removed. How you do this stuff will depend on your code requirements.