在WPF中创建故事板?
我有很多论文:在WPF中创建故事板?
<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>
如果有人点击上面三张图片中的任何一张,我该如何让动画开火?他们共同分享的东西是风格,所以也许有一些方法可以使用它?
有什么建议吗?
如果具有触发器的Grid
是所有图像的父级,那么MouseDown
事件将从每个图像冒泡到它,因此您只需从trigger中删除SourceName
设置。
否则,您可以将SourceName
设置为Image的父级。
如果我正确理解您的问题,那就是您不希望多次重复相同的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
被触发时才会运行。
希望这会有所帮助!