【问题标题】:Prevent KeyDown event bubbling from TextBox to MainWindow in WPF防止KeyDown事件从TextBox冒泡到WPF中的MainWindow
【发布时间】:2011-11-03 09:15:23
【问题描述】:

我有一个包含文本框控件的程序。用户可以在此控件中输入文本。用户还可以按下某些键来触发其他操作(这在 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 方法,但在这种情况下,在TextBoxKeyDown 事件上这样做会阻止输入文本。如果这不可能,我将不得不寻找其他方法来处理这一切。

提前致谢。

编辑

我刚刚找到了解决这个问题的一种比较老套的方法。如果我改为处理 MainWindow 的 OnTextInput 方法,那么我想要的结果将得到实现,因为 TextBoxTextInput 事件将得到处理。下面是我使用的代码示例:

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 ...
}

【问题讨论】:

  • 你为什么不用InputBindings做这种事?
  • 我刚刚尝试过,它阻止我在文本框中输入内容。
  • 哦,没想到,真不幸。
  • e.Handled = true;不会吗?

标签: c# wpf event-bubbling event-routing


【解决方案1】:

您可以在该语句上放置基于类型的保护:

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);

    if (e.OriginalSource is TextBoxBase == false)
    {
        mPressedKey = e.Key;
    }
}

虽然也很可能不是最好的解决方案。

【讨论】:

    【解决方案2】:

    我最终使用以下设置解决了这个问题:

    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);
    }
    

    这是在 MainWindow.xaml.cs 中完成的。这有点 hack,但它达到了我想要的结果。

    【讨论】:

      猜你喜欢
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      • 2012-04-25
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多