在WPF中启动故事板?

在WPF中启动故事板?,wpf,animation,Wpf,Animation,我有许多论文: <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" To

我有许多论文:

<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"/>
如果有人单击上面三幅图像中的任何一幅,我如何使动画启动?他们的共同点是风格,所以也许有什么方法可以使用它


有什么建议吗?

如果我正确理解您的问题,那就是您不想重复相同的
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>
在本例中,将对每个
矩形应用样式,并将附加的行为配置为拦截
MouseDown
路由事件,并将此事件替换为
InterceptedEvent
。然后,仅当触发
InterceptedEvent
时,动画才会运行


希望这有帮助

如果带触发器的
网格
是所有图像的父级,那么
MouseDown
事件将从每个图像中冒泡出来,因此您所要做的就是从触发器中删除
SourceName
设置

否则,您可以将
SourceName
设置为图像的父级

<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));
        }
    }
}