[英]Prevent KeyDown event bubbling from TextBox to MainWindow in WPF
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).
用户还可以按某些键来触发其他操作(这在MainWindow中处理)。 I have sample XAML and C# code to demonstrate my setup.
我有示例XAML和C#代码来演示我的设置。
XAML 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# 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. 您可能已经意识到,在此程序中,如果我开始在第一个
TextBox
键入内容,则第二个将使用命中计数进行更新。 This is an undesirable result as I might have certain actions that I wish to trigger when handling the MainWindow's OnKeyDown
method. 这是不理想的结果,因为在处理MainWindow的
OnKeyDown
方法时,我可能希望触发某些动作。
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? 因此,我的问题是这样的:是否可以防止在MainWindow上调用
OnKeyDown
方法,同时仍然允许将文本输入到文本框中? 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. 我知道
e.Handled = true
方法,但是在这种情况下,对TextBox
的KeyDown
事件执行此操作将阻止输入文本。 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. 如果我改为处理MainWindow的
OnTextInput
方法,则将实现我所需的结果,因为将处理TextBox
的TextInput
事件。 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 ...
}
You could put a type-based guard on that statement: 您可以在该语句上放置基于类型的防护:
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.OriginalSource is TextBoxBase == false)
{
mPressedKey = e.Key;
}
}
Quite possibly not the best solution either though. 不过,可能也不是最好的解决方案。
I ended up working around this issue using the following setup: 我最终使用以下设置解决了这个问题:
private Key mPressedKey;
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
mPressedKey = e.Key;
}
protected override void OnTextInput(TextCompositionEventArgs e)
{
base.OnTextInput(e);
// ... Handle mPressedKey here ...
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
// Force focus back to main window
FocusManager.SetFocusedElement(this, this);
}
This was done in the MainWindow.xaml.cs. 这是在MainWindow.xaml.cs中完成的。 It's a bit of a hack, but it achieved the result I wanted.
这有点hack,但是达到了我想要的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.