我有以下路由事件:
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。但是,引发路由事件(通过单击按钮)不会发生任何事情(没有错误,只是没有)。不确定是什么问题。
对此有什么正确的解决方法?
答案 0 :(得分:1)
您可能误解了tunneling的工作方式:
隧道:最初,调用元素树根的事件处理程序。然后,路由事件沿着路径传递路径中的连续子元素,朝向作为路由事件源的节点元素(引发路由事件的元素)。
此处事件将从根,窗口到源,也是窗口,它永远不会遇到TextBlocks
。您可能需要在所有这些事件上引发事件或者在窗口上监听事件,遗憾的是您无法在样式中使用EventTrigger.SourceName
。可悲的是,我不知道有什么好的解决方案......
(您可以使用EventSetter
来处理Loaded
的{{1}}事件,然后在窗口上收听事件并在本地重新提升(您将想要改变路由策略,否则如果你没有检查事件的来源,你会得到一个堆栈溢出异常),如果这是个好主意可能会有问题)