2011-09-22 21 views
1

我的路由事件触及子元素之前的根UI元素。这是预期的吗?我怎样才能让路由事件首先碰到子元素?路由事件问题 - 在子元素之前触击根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; 
     } 
    } 
} 

回答

2

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

从MSDN,UIElement.PreviewTextInput Event

路由策略 - 隧道

相应的冒泡事件为TextInput。

Routed Events Overview - Routing Strategies:

冒泡:事件源的事件处理程序调用。然后,路由到的事件将路由到连续的父元素,直到到达元素树根目录为止,即 事件。大多数路由事件使用冒泡路由 策略。冒泡路由事件通常用于报告从不同的控制或其他UI元素

直接输入或 状态变化:只有源元件本身被给予机会 调用处理程序来响应。这类似于Windows窗体用于事件的“路由”。但是,与标准CLR事件不同, 直接路由事件支持类处理(在下一节中解释类处理为 ),并且可以由EventSetter和 使用EventTrigger。

隧道:最初,调用元素树根处的事件处理程序 。然后,路由事件沿着路径传播沿路由的子元素的路由,朝向作为路由事件源(引发路由事件的元素)的节点元素。 隧道路由事件经常被用作或处理为合成控件的一部分,使得来自复合材料部件的事件可以被故意压制或被特定于完全控制的事件替代。在WPF中提供的输入事件通常以实现为隧道/冒泡对的形式实现。隧道事件也是 有时被称为预览事件,因为用于配对的命名约定为 。