2013-04-23 69 views
1

我读的MSDN动画教程,它介绍了以下步骤将故事板应用于元素:如何使一个元素在XAML中引用的StaticResource故事板(而不是故事板引用元素)

  1. 创建故事板;
  2. 使用TargetName属性指定其目标元素名称;
  3. (指定目标属性);
  4. (添加一个事件触发器来启动动画);

我看到一个概念性的问题,从中得出我的难处,那就是:

我有故事板和元件之间的一个一对一的关系,而这种关系在故事板定义。那么,我如何创建一个Storyboard,并有条件地将它应用于多个元素,触发动画FROM ELEMENT ITSELF(通过绑定/触发器,我想)。

我打算用例是mimmick LED的面板(椭圆的一个StackPanel),其中每个LED可以在四种逻辑状态:开机,关机,快速闪烁,并缓慢闪烁(很像以太网路由器)。然后,我会创建动画BlinkingSlowBlinkingFast,然后在我的ViewModel进入相应的逻辑状态时触发该动画。然后,我可以只关心ViewModel中的行为,并让View自己照顾自己,正确触发并重用一些StaticResource Storyboard。

<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> 

有什么建议吗?

回答

1

你可以使用风格触发器。

像你已经做的那样在资源部分创建你的故事板,但没有目标名称。

然后,您为包含DataTrigger的椭圆创建样式,开始您当前状态所需的动画。

例如:

<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> 
+0

要去给它一个尝试,看起来像一个很好的解决方案,我只要一有新的信息,我会给予反馈,谢谢! – heltonbiker 2013-04-23 16:13:00

+0

你介意如何实现我的ViewModel(用作DataContext)吗?假设我有我的LedsPanelViewModel,名为“State”的属性,我应该如何设置这个属性?像这样的字符串'this.State =“BlinkSlowState”'例如,或者我应该创建一个枚举?我很困惑... – heltonbiker 2013-04-23 16:36:25

+0

我做到了,并且它的'Value'属性是一个字符串。非常感谢你!! – heltonbiker 2013-04-23 17:10:24