问题概述:
在高于TextBox
的级别上定义的任何KeyBinding
(未分配修饰键),将阻止用户在TextBox
中键入这些键。
最小XAML层次结构:
<Window>
<UserControl>
<Border>
<UserControl>
<TextBox>
最小命令/键绑定:
<UserControl.Resources>
<RoutedUICommand x:Key="Commands.SomeCommand" />
</UserControl.Resources>
<UserControl.InputBindings>
<KeyBinding Key="A" Command="{StaticResource Commands.SomeCommand}" />
</UserControl.InputBindings>
<UserControl.CommandBindings>
<CommandBinding Command="{StaticResource Commands.SomeCommand}" Executed="..." />
</UserControl.CommandBindings>
Command
和KeyBinding
是在firstUserControl
级别定义的,所以在这个例子中,在文本框中,用户可以自由输入,直到他们按下A
键,然后它就不把字母插入文本框了。我可以清楚地看到当你按下A
键时TextBox.KeyDown
和TextBox.PreviewKeyDown
正在发射(和Handled = false
),但字母不会添加到文本框的文本中,并且TextBox.PreviewTextInput
不会触发。
我正在寻找任何建议,这些建议可能会指出是什么吞噬了按键并阻止TextBox处理它,或者与如何调试此问题相关的任何建议。
编辑:
多亏了Snoop,我才能清楚地看到问题所在。
TextBox.PreviewKeyDown
向下通过隧道并通过可视树触发,从Window开始,到TextBox结束TextBox.KeyDown
从TextBox开始向窗口方向返回TextBox.KeyDown
会由第一个设定KeyBinding的UserControl将Handled设定为true。TextBox.PreviewTextInput
永远不会引发,文字方块也不会行程输入,因为KeyDown事件已设定为已行程。
这仍然留下了一个问题,如果文本框具有焦点,如何防止UserControl处理输入?在命令执行中,我可以检查文本框是否具有键盘焦点,但此时已经太晚了。
4条答案
按热度按时间jum4pzuy1#
TextInput
和PreviewTextInput
仅在文本实际更改/可能更改时触发。当您更新问题以反映时,
Command
会拦截事件,且永远不会引发(Preview)TextInput事件。最好的解决方案是在KeyBinding中添加一个修饰键,但我怀疑这不是您的首选方法。
另一种方法是对TextBox上的PreviewKeyDown事件执行
e.Handle
操作,然后自己引发TextComposition事件,方法如下:(或者,在正确的
CaretIndex
处插入textBox.Text
)说实话,这仍然是一个黑客。
pbgvytdp2#
我也有同样的问题。我看了一下key bindind的文档,上面描述了,绑定的键不应该只是key,而是key gesture,所以它应该是
当然,它只适用于A,但总体来说这是一种糟糕的做法。您应该考虑实现后面提到的一些可能性。更多信息请访问https://msdn.microsoft.com/cs-cz/library/system.windows.input.keybinding(v=vs.110).aspx
lkaoscv73#
我已经使用TextComposition RaiseEvent方法很多年了,但是这似乎破坏了非拉丁键盘布局(如西里尔字母)的输入。
执行此操作的正确方法是从InputBinding派生,如果事件源自文本框,则在
Matches?
检查中返回false。现在您有了一个InputGesture,它将忽略来自文本框的事件,您可以像平常一样在XAML中使用它:
pgccezyw4#
只要你使用
KeyBinding
,这将不会工作,没有主要的黑客。我实现的解决方案是:1.使用
KeyDown
事件来捕获那些被按下的键(而不是KeyBindings
)。这将在代码隐藏中,从那里你需要打开被按下的键来调用所需的命令(在你的例子中是SomeCommand
)。1.现在你有了一个不同的问题。
TextBox
正在获取输入,但是你的键绑定命令也在触发。在后面的代码中,检查keyEventArgs.InputSource
的类型,如果是TextBox
,则忽略击键。它应该如下所示: