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