2012-02-10 49 views
2

我有以下路由事件:處理窗口的RoutedEvent在許多WPF元素與風格

public static readonly RoutedEvent FakeEvent = EventManager.RegisterRoutedEvent(
    "Fake", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(MainWindow)); 
public event RoutedEventHandler Fake 
{ 
    add { AddHandler(FakeEvent, value); } 
    remove { RemoveHandler(FakeEvent, value); } 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    RoutedEventArgs newEventArgs = new RoutedEventArgs(MainWindow.FakeEvent); 
    RaiseEvent(newEventArgs); 
} 

我有以下XAML:

<Window.Resources> 

    <Style TargetType="{x:Type TextBlock}" 
     xmlns:local="clr-namespace:WpfApplication1"> 
     <Setter Property="Margin" Value="10" /> 
     <Setter Property="Background" Value="Red" /> 
     <Style.Triggers> 
      <EventTrigger RoutedEvent="local:MainWindow.Fake"> 
       <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation To="Blue" Duration="0:0:1" 
          Storyboard.TargetProperty="Background.Color" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Style.Triggers> 
    </Style> 

</Window.Resources> 

<StackPanel> 
    <Button Click="Button_Click">Raise Event</Button> 
    <TextBlock>Hello World</TextBlock> 
    <TextBlock>Hello World</TextBlock> 
    <TextBlock>Hello World</TextBlock> 
    <TextBlock>Hello World</TextBlock> 
    <TextBlock>Hello World</TextBlock> 
    <TextBlock>Hello World</TextBlock> 
</StackPanel> 

我的目標是,窗口的路由事件將導致故事板通過使用可重用的通用樣式來觸發所有TextBlocks。但是,引發路由事件(通過單擊按鈕)不會產生任何結果(沒有錯誤,只是沒有)。不知道有什麼問題。

什麼是正確的方法呢?

回答

1

你可能誤會了怎麼tunneling作品:

隧道:最初,在元素樹的根事件處理程序被調用。然後,路由的事件沿着路徑傳播通過連續子元素的路由,朝向作爲路由事件源的節點元素(引發路由事件的元素)。

在這裏,事件將從根本,窗口旅行,來源,也是窗口,它永遠不會碰到TextBlocks。您可能需要在所有人中舉辦活動或在窗口上聆聽活動,但不幸的是,您不能在款式中使用EventTrigger.SourceName。可悲的是,我不知道有什麼好的解決了這個的......

(你可以使用一個EventSetter處理Loaded事件TextBlocks到後來聽窗口和事件在當地再提高它(你將要改變路由策略,否則如果你不檢查事件來自哪裏,你會得到一個堆棧溢出異常),如果這是一個好主意,可能會有疑問)