路由事件问题-在子元素之前击中根UI元素

本文关键字:元素 UI 路由 问题 事件 | 更新日期: 2023-09-27 18:09:28

我的路由事件在子元素之前击中根UI元素。这是意料之中的吗?如何让路由事件首先击中子元素?

目的:如果文本输入到"自定义文本框"以外的任何地方,请将文本输入到"默认文本框"

结果:Window_PreviewTextInput在custom_PreviewTextInput之前被击中,即使我的光标焦点是在"自定义文本框"

我应该怎么做?


XAML

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight"
        PreviewTextInput="Window_PreviewTextInput"
        >
    <Grid Margin="100,100,100,100">
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="default" Width="100"/>
                <TextBox x:Name="defaultTB" Width="300" Height="50"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="custom" Width="100"/>
                <TextBox x:Name="custom" PreviewTextInput="custom_PreviewTextInput" Width="300" Height="50"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        //goal:  if text is typed anywhere except custom textbox, put text in default textbox
        private void Window_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            Keyboard.Focus(defaultTB); 
        }
        //goal:  if text is typed in custom TB, put text there, and end the event routing
        private void custom_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            e.Handled = true; 
        }
    }
}

路由事件问题-在子元素之前击中根UI元素

路由事件可以是冒泡或隧道。你有一个隧道事件行为。

From MSDN, UIElement。PreviewTextInput事件:

路由策略-隧道

对应的冒泡事件为TextInput。

路由事件概述-路由策略:

冒泡:调用事件源上的事件处理程序。的路由事件然后路由到连续的父元素,直到到达元素树根。大多数路由事件使用冒泡路由策略。冒泡路由事件通常用于报告输入或不同控件或其他UI元素的状态变化

直接:只有源元素本身有机会在响应中调用处理程序。这类似于"路由"。那Windows窗体用于事件。然而,与标准的CLR事件不同,直接路由事件支持类处理(类处理是在接下来的部分中解释),并且可以被EventSetter和EventTrigger .

Tunneling:最初,元素树根部的事件处理程序是调用。然后路由事件通过连续的路由传播子元素沿着路由,指向节点元素路由事件源(引发路由事件的元素)。的一部分使用或处理隧道路由事件为控件进行复合,以便来自复合部件的事件可以被刻意压制或被特定的事件所取代完全控制。WPF中提供的输入事件经常出现作为隧道/冒泡对实现。隧道事件也是有时被称为预览事件,因为命名