我有一个带有文本框的窗口,该窗口在键入时不会引发textInput事件。
我一直在和Snooper一起看它。仅抛出KeyDown和KeyUp事件。
它 IS 响应几个键:空格键,退格键,插入键,起始键,删除键,结束键
它响应复制和粘贴命令以及全选
它不响应任何字符,符号或数字
这是启动程序::此窗口是通过共享方法打开的,该共享方法从代码中的两个不同位置调用。从一个位置调用时,文本框可以完美运行,而从另一位置调用时,则不能。
我已经排除了绑定,数据转换器,样式,控件位置。 我将窗口剥离为一个没有绑定的纯文本框,问题仍然存在。
我已尽我所能来查找此神秘错误。我看不到在甚至未抛出PreviewTextInput之前可能处理我的事件的原因,或者为什么它可能只发生一半的时间。
有关此错误原因的任何想法,或我可以尝试跟踪事件的其他工具,将不胜感激!
编辑:添加一些代码进行演示。该代码已被精简为所需的Barest代码,并且问题仍然存在。
<Window x:Class="EventViewEmail"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="880" Height="600">
<TextBox VerticalAlignment="Top"/>
</Window>
请注意缺少绑定,样式或其他可能干扰控件的内容
Public Class EventViewEmail
'all code removed from the view-behind'
End Class
这是构建窗口的静态类。对此类的两个单独调用以不同的方式构建参数。我已经删除了使用自变量来表明它们不会影响当前问题的代码。
Public Class EventManager
Public Shared Sub Show(e As EventEdit, p As WorkplanPageViewModel)
Dim w = New EventViewEmail
If w Is Nothing Then Return
'removed datacontext for testing'
'w.DataContext = e '
'w.Tag = p'
w.Show()
End Sub
End Class
我唯一可以添加的是调用Show()子代码的代码来自两个单独的解决方案。不确定删除所有参数后可能产生的影响
修改2: 我一直试图跟踪事件序列,以缩小处理事件的位置。到目前为止,我可以看到在keyDown和keyUp事件之间,发生了一系列应该 发生的事件,而不是:
keydown事件没有得到处理,所以我不确定为什么没有触发PreviewInputReport
答案 0 :(得分:2)
我将发布 C#代码,因为我不太熟练 VB 来编写代码(只能在有限的范围内读取)。如果有时间,我会尝试翻译,否则任何人都可以随意翻译。
我已经通过在窗口的可视树上处理PreviewTextInput
事件来重现您描述的行为(记住这是隧道路由事件):
<Window (...)>
<StackPanel>
<TextBox x:Name="myTextBox"></TextBox>
</StackPanel>
</Window>
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
PreviewTextInput += (s, e) => e.Handled = true;
}
}
因此,我认为这很可能是您造成问题的原因。它还说明the comment to @AQuirky's answer未调用您的PreviewTextInput
处理程序。您可以通过不同的订阅来确认是这种情况(即使事件被标记为已处理,也会调用处理程序):
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
PreviewTextInput += (s, e) => e.Handled = true;
myTextBox.AddHandler(
routedEvent: PreviewTextInputEvent,
handler: new TextCompositionEventHandler((s, e) =>
{
if (e.Handled)
throw new Exception("Gotcha!");
}),
handledEventsToo: true);
}
}
如果这确实是正确的诊断,那么有一件事有些神秘-谁和在哪里处理PreviewTextInput
事件?我想这是您要调查的...
This comment from @l33t可能会派上用场:
查找诸如EventManager.RegisterClassHandler(typeof(TextBox),UIElement.PreviewTextInputEvent,...)之类的全局事件处理程序和/或行为。您是否正在使用任何第三方UI库?还要查看他们的代码。
由于看来PreviewTextInput
毕竟不是罪魁祸首,所以这就是我接下来要做的事情。
如果我没记错的话,会在TextInputEvent
之前触发整个事件链,我相信处理这些事件中的任何一个都会破坏链。看起来InputManager
负责管理此事件周期(您可以查看其 C#源代码here)。
话虽如此,我建议您进行以下操作:
InputManager.Current
订阅其PreProcessInput
和/或PostProcessInput
事件(还可以选择PreNotifyInput
和PostNotifyInput
)StagingItem.Input.RoutedEvent
,该参数包含当前正在处理的路由事件)答案 1 :(得分:0)
问题是,在触发TextInput时(未引发...抛出异常),您没有看到它,因为文本框本身正在使用它。要捕获此事件,您需要使用PreviewTextInput。例如
<TextBox TextInput="UIElement_OnTextInput" PreviewTextInput="UIElement_OnPreviewTextInput"></TextBox>
具有事件处理程序...
private void UIElement_OnTextInput(object sender, TextCompositionEventArgs e)
{
Console.WriteLine($"In text input event, {e.Text}");
}
private void UIElement_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
Console.WriteLine($"In preview text input event, {e.Text}");
}
从不调用第一个处理程序,始终调用第二个处理程序。
答案 2 :(得分:0)
在这种情况下,事实证明在不工作的情况下启动窗口的表单是winform。 Winform阻止了击键。通过将窗口作为模式打开来解决此问题。
答案 3 :(得分:0)
未调用您的处理程序,因为其他处理程序已将该事件标记为已处理。您可以添加带有AddHandler()
的处理程序,并为第三个参数传递true
:
public MainWindow()
{
var handler = new RoutedEventHandler(OnTextInput);
myTextBox.AddHandler(TextInputEvent, handler, handledEventsToo: true);
}
private static void OnTextInput(object sender, RoutedEventArgs e)
{
}
答案 4 :(得分:0)