我有很多论文:
<Image x:Name="Foo" Grid.Column="0" Grid.Row="0" Source="1.png" Style="{StaticResource imageStyle}"
ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="fffffff"/>
<Image x:Name="Foo2" Grid.Column="1" Grid.Row="0" Source="2.png" Style="{StaticResource imageStyle}"
ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="eeeeeeeee"/>
<Image x:Name="Foo3" Grid.Column="2" Grid.Row="0" Source="3.png" Style="{StaticResource imageStyle}"
ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="ddddddddddddd"/>
现在我的动画故事板只有在有人点击Foo
图片时才会触发。
<Grid.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown" SourceName="Foo">
<BeginStoryboard Name="mySlider">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="contentHolder"
Storyboard.TargetProperty="Margin"
Duration="0:0:1" From="0 0 0 0" To="-800 0 0 0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
如果有人点击上面三张图片中的任何一张图片,我该如何制作动画?他们共同的共同点是风格,所以也许有一些方法可以使用它?
有什么建议吗?
答案 0 :(得分:1)
如果我正确理解您的问题,那就是您不希望多次重复相同的EventTrigger
次,每次来源一次。如果您遗漏SourceName
,那么即使不是来自您的某个图片,您的动画也会针对任何未处理的MouseDown
路由事件启动(因为MouseDown
是一个非常通用的冒泡路由事件)
一个解决方案是拥有一个自定义Image
类(可能称为MyImage
),它将检测MouseDown
事件何时发生,并作为响应触发一个非常自定义的RoutedEvent
(说MyImageRoutedEvent
)。然后,您EventTrigger
可以收听MyImageRoutedEvent
,因为只有MyImage
可以触发此事件。因此,仅当MouseDown
事件来自您的MyImage
个实例之一时,才会运行动画。
或者,您可以通过附加行为实现此行为。我们的想法是将行为配置为拦截指定的事件(通过附加属性),并且当从参与该行为的元素触发该事件时,该事件被标记为已处理并且将触发新的自定义事件。然后,您的EventTrigger
会收听新的自定义事件。
示例XAML:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="rectangleStyle" TargetType="{x:Type Rectangle}">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="l:EventInterceptBehaviour.OriginalRoutedEvent" Value="UIElement.MouseDown" />
</Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<StackPanel>
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Red" />
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Green" />
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Blue" />
<Border BorderBrush="Black" x:Name="contentBorder">
<ContentPresenter HorizontalAlignment="Center"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="l:EventInterceptBehaviour.InterceptedEvent">
<BeginStoryboard Name="mySlider">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="contentBorder"
Storyboard.TargetProperty="BorderThickness"
Duration="0:0:1" To="10" FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ContentControl Content="Content Placeholder" />
</StackPanel>
示例行为:
public static class EventInterceptBehaviour
{
#region InterceptedEvent Attached Routed Event
public static readonly RoutedEvent InterceptedEventEvent = EventManager.RegisterRoutedEvent("InterceptedEvent",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(EventInterceptBehaviour));
public static void AddInterceptedEventHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.AddHandler(InterceptedEventEvent, handler);
}
}
public static void RemoveInterceptedEventHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.RemoveHandler(InterceptedEventEvent, handler);
}
}
#endregion
#region OriginalRoutedEvent Attached Dependency Property
public static void SetOriginalRoutedEvent(FrameworkElement element, RoutedEvent value)
{
element.SetValue(OriginalRoutedEventProperty, value);
}
public static RoutedEvent GetOriginalRoutedEvent(FrameworkElement element)
{
return (RoutedEvent)element.GetValue(OriginalRoutedEventProperty);
}
public static readonly DependencyProperty OriginalRoutedEventProperty =
DependencyProperty.RegisterAttached("OriginalRoutedEvent", typeof(RoutedEvent),
typeof(EventInterceptBehaviour),
new FrameworkPropertyMetadata(OnOriginalRoutedEventPropertyChanged));
#endregion
private static void OnOriginalRoutedEvent(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
element.RaiseEvent(new RoutedEventArgs(InterceptedEventEvent, element));
e.Handled = true;
}
private static void OnOriginalRoutedEventPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.AddHandler((RoutedEvent)e.NewValue, new RoutedEventHandler(OnOriginalRoutedEvent));
}
}
}
在此示例中,样式应用于每个Rectangle
,并且附加行为配置为拦截MouseDown
路由事件,并将此事件替换为InterceptedEvent
。然后,只有在InterceptedEvent
被触发时才会运行动画。
希望这有帮助!
答案 1 :(得分:1)
如果带有触发器的Grid
是所有图片的父级,则MouseDown
事件无论如何都会从每个图片冒泡到它,所以您只需删除{{1}从触发器设置。
否则,您可以将SourceName
设置为Image的父级。