2011-09-22 54 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中提供的輸入事件通常以實現爲隧道/冒泡對的形式實現。隧道事件也是 有時被稱爲預覽事件,因爲用於配對的命名約定爲 。