如何使元素引用XAML中的StaticResource故事板(而不是引用该元素的故事板) [英] How to make an element reference a StaticResource Storyboard in XAML (instead of the storyboard referencing the element)
问题描述
我正在阅读MSDN Animation教程,它描述了将情节提要应用于元素的以下步骤:
I am reading the MSDN Animation tutorial, and it describes the following steps to apply a storyboard to an element:
- 创建情节提要;
- 使用
TargetName
属性指定其目标元素名称; - (指定目标属性);
- (添加事件触发器以启动动画);
- Create the Storyboard;
- Specify its target element name with the
TargetName
property; - (Specify the target property);
- (Add an event trigger to start the animation);
我看到了从中得出问题的一个概念性问题是:
I see a conceptual problem, from which derives my difficulty, that's this:
我在情节提要和元素之间存在一对一的关系,并且此关系在情节提要中定义。然后,如何创建一个情节提要板,并有条件地将其应用于多个元素,从而触发元素本身中的动画(我想是通过绑定/触发器)。
I have a one-to-one relationship between storyboard and element, and this relationship is defined in the storyboard. Then, how could I create ONE storyboard, and conditionally apply it to more than one element, triggering the animation FROM THE ELEMENT ITSELF (via Binding / Triggers, I suppose).
我打算用的用例是模拟一个led面板(一堆椭圆),其中每个led可以处于以下四种逻辑状态之一:开,关,快速闪烁和缓慢闪烁(漂亮)就像以太网路由器一样)。然后,我将创建动画 BlinkingSlow
和 BlinkingFast
,然后在我的ViewModel输入相应的逻辑时触发状态。然后,我可以关心一下ViewModel中的行为,并通过适当触发和重用一些StaticResource Storyboard来让View照顾好自己。
My intended use case is to mimmick a panel of leds (a stackpanel of ellipses) where each led can be in one of four logical states: on, off, blinking fast, and blinking slow (pretty much like ethernet routers do). Then, I'd create the animations BlinkingSlow
and BlinkingFast
, which would then be triggered when my ViewModel entered the respective logical states. Then I could just care about behavior in the ViewModel and let the View take care of itself, with proper triggering and reuse of a few StaticResource Storyboards.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:blinking"
x:Class="blinking.MainWindow"
Title="MainWindow"
Background="{x:Null}"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<System:Double x:Key="Diameter">40</System:Double>
<Color x:Key="RedOn">Red</Color>
<Color x:Key="RedOff">#FF570000</Color>
<Storyboard x:Key="BlinkSlow" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
Storyboard.TargetName="led4"
AutoReverse="True"
RepeatBehavior="Forever">
<DiscreteColorKeyFrame KeyTime="0" Value="{StaticResource RedOn}"/>
<DiscreteColorKeyFrame KeyTime="0:0:0.5" Value="{StaticResource RedOn}"/>
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="{StaticResource RedOff}"/>
<DiscreteColorKeyFrame KeyTime="0:0:1" Value="{StaticResource RedOff}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource BlinkSlow}"/>
</EventTrigger>
</Window.Triggers>
<StackPanel x:Name="leds_container" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,20,4,0">
<Ellipse x:Name="led1" Width="{StaticResource Diameter}" Height="{StaticResource Diameter}" Fill="#FFF90F0F" Margin="20,0,0,0"/>
<Ellipse x:Name="led2" Width="{StaticResource Diameter}" Height="{StaticResource Diameter}" Fill="#FFF90F0F" Margin="20,0,0,0"/>
<Ellipse x:Name="led3" Width="{StaticResource Diameter}" Height="{StaticResource Diameter}" Fill="#FFF90F0F" Margin="20,0,0,0"/>
<Ellipse x:Name="led4" Width="{StaticResource Diameter}" Height="{StaticResource Diameter}" Fill="#FFF90F0F" Margin="20,0,0,0"/>
</StackPanel>
</Window>
有任何建议吗?
推荐答案
您可以为此使用样式触发器。
You can use Style-Triggers for that.
像已经一样在资源部分中创建故事板,但没有目标名称。
Create your storyboard in the Resources-section like you already did, but without a target name.
然后,为椭圆创建一个样式,其中包括一个DataTrigger,以启动当前状态所需的动画。
Then you create a style for your ellipse which includes a DataTrigger, starting the animation you need for your current state.
例如:
<Window.Resources>
<!--
Other declarations
-->
<Style TargetType="{x:Type Ellipse}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=State, Mode=OneWay}" Value="BlinkSlow">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource BlinkSlow}" />
</DataTrigger.EnterActions>
</DataTrigger>
<!--
Add DataTrigger for your other states too.
-->
</Style.Triggers>
</Style>
</Window.Resources>
这篇关于如何使元素引用XAML中的StaticResource故事板(而不是引用该元素的故事板)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!