防止 WPF 中的 KeyDown 事件从 TextBox 冒泡到 MainWindow
我有一个包含文本框控件的程序。用户可以在此控件中输入文本。用户还可以按某些键来触发其他操作(这是在主窗口上处理的)。我有示例 XAML 和 C# 代码来演示我的设置。
XAML
<Window x:Class="RoutedEventBubbling.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" />
<TextBox x:Name="Output" Grid.Row="1" IsReadOnly="True" />
</Grid>
</Window>
C#
using System.Windows;
using System.Windows.Input;
namespace RoutedEventBubbling
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private int mHitCount = 0;
public MainWindow()
{
InitializeComponent();
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);
}
}
}
正如您可能已经意识到的,在这个程序中,如果我开始在第一个 TextBox
中输入内容,第二个文本框将更新为点击次数。这是一个不受欢迎的结果,因为我可能希望在处理 MainWindow 的 OnKeyDown
方法时触发某些操作。
因此,我的问题是:是否可以阻止在 MainWindow 上调用 OnKeyDown 方法,同时仍然允许在文本框中输入文本?我知道 e.Handled = true
方法,但在这种情况下,在 TextBox
的 KeyDown
事件上执行此操作将阻止文本被输入。如果这是不可能的,我将不得不寻找其他方法来处理这一切。
提前致谢。
编辑
我刚刚找到了解决这个问题的一种适度的黑客方法。如果我改为处理 MainWindow 的 OnTextInput
方法,那么我想要的结果将会实现,因为 TextBox
的 TextInput
事件将被处理。下面是我使用的代码示例:
private Key mPressedKey;
protected override void OnKeyDown(KeyEventArgs e)
{
// Note: This method will be called first.
base.OnKeyDown(e);
// Store the pressed key
mPressedKey = e.Key;
}
protected override void OnTextInput(TextCompositionEventArgs e)
{
// Note: This method will be called second, and only if the textbox hasn't handled it.
base.OnTextInput(e);
this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);
// ... Handle pressed key ...
}
I have a program that contains a textbox control. A user is able to enter text into this control. The user can also press certain keys to trigger other actions (this is handled on the MainWindow). I have sample XAML and C# code to demonstrate my setup.
XAML
<Window x:Class="RoutedEventBubbling.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" />
<TextBox x:Name="Output" Grid.Row="1" IsReadOnly="True" />
</Grid>
</Window>
C#
using System.Windows;
using System.Windows.Input;
namespace RoutedEventBubbling
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private int mHitCount = 0;
public MainWindow()
{
InitializeComponent();
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);
}
}
}
As you may have realised, in the case of this program, if I start typing into the first TextBox
the second will be updated with the hit count. This is an undesirable result as I might have certain actions that I wish to trigger when handling the MainWindow's OnKeyDown
method.
As such, my question is this: is it possible to prevent the OnKeyDown
method being called on the MainWindow, while still allowing text to be entered into the text box? I know of the e.Handled = true
approach, but in this case doing that on the KeyDown
event of the TextBox
will prevent the text from being entered. If this is not possible, I will have to find some other way of handling it all.
Thanks in advance.
EDIT
I have just found a moderately hacky way around this issue. If I handle the MainWindow's OnTextInput
method instead, then the result I desired will be achieved as the TextInput
event of the TextBox
will have been handled. Below is a sample of the code I used:
private Key mPressedKey;
protected override void OnKeyDown(KeyEventArgs e)
{
// Note: This method will be called first.
base.OnKeyDown(e);
// Store the pressed key
mPressedKey = e.Key;
}
protected override void OnTextInput(TextCompositionEventArgs e)
{
// Note: This method will be called second, and only if the textbox hasn't handled it.
base.OnTextInput(e);
this.Output.Text = string.Format("Hit Count: {0}", ++mHitCount);
// ... Handle pressed key ...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以在该语句上放置基于类型的保护:
但这很可能不是最好的解决方案。
You could put a type-based guard on that statement:
Quite possibly not the best solution either though.
我最终使用以下设置解决了这个问题:
这是在 MainWindow.xaml.cs 中完成的。虽然有点hack,但它达到了我想要的结果。
I ended up working around this issue using the following setup:
This was done in the MainWindow.xaml.cs. It's a bit of a hack, but it achieved the result I wanted.