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

发布于 2024-12-06 00:23:30 字数 2358 浏览 1 评论 0原文

我的路由事件在子元素之前先到达根 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; 
        }
    }
}

My routed events are hitting the root UI element before the child element. Is this expected? How can I have the routed events hit the child element first?

Objective: If text is typed anywhere other than "custom textbox", put text in "default textbox"

Result: Window_PreviewTextInput is being hit before custom_PreviewTextInput, even if my cursor focus is on "Custom Textbox"

What should I do differently?


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>

Code Behind:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

许久 2024-12-13 00:23:30

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

来自 MSDN,UIElement.PreviewTextInput 事件

路由策略 - 隧道

对应的冒泡事件是TextInput。

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

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

直接:只有源元素本身才有机会
调用处理程序作为响应。这类似于“路由”
Windows 窗体用于事件。但是,与标准 CLR 事件不同,
直接路由事件支持类处理(类处理是
将在下一节中解释)并且可以由 EventSetter 和
事件触发器。

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

Routed Event could be a bubbling or tunneling. You've a tunneling event behaviour.

From MSDN, UIElement.PreviewTextInput Event:

Routing strategy - Tunneling

The corresponding bubbling event is TextInput.

Routed Events Overview - Routing Strategies:

Bubbling: Event handlers on the event source are invoked. The routed
event then routes to successive parent elements until reaching the
element tree root. Most routed events use the bubbling routing
strategy. Bubbling routed events are generally used to report input or
state changes from distinct controls or other UI elements

Direct: Only the source element itself is given the opportunity to
invoke handlers in response. This is analogous to the "routing" that
Windows Forms uses for events. However, unlike a standard CLR event,
direct routed events support class handling (class handling is
explained in an upcoming section) and can be used by EventSetter and
EventTrigger.

Tunneling: Initially, event handlers at the element tree root are
invoked. The routed event then travels a route through successive
child elements along the route, towards the node element that is the
routed event source (the element that raised the routed event).
Tunneling routed events are often used or handled as part of the
compositing for a control, such that events from composite parts can
be deliberately suppressed or replaced by events that are specific to
the complete control. Input events provided in WPF often come
implemented as a tunneling/bubbling pair. Tunneling events are also
sometimes referred to as Preview events, because of a naming
convention that is used for the pairs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文