How to make an element reference a StaticResource Storyboard in XAML (instead of the storyboard referencing the element)

吃可爱长大的小学妹 提交于 2020-01-04 04:58:25

问题


I am reading the MSDN Animation tutorial, and it describes the following steps to apply a storyboard to an element:

  1. Create the Storyboard;
  2. Specify its target element name with the TargetName property;
  3. (Specify the target property);
  4. (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).

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>

Any suggestion?


回答1:


You can use Style-Triggers for that.

Create your storyboard in the Resources-section like you already did, but without a target name.

Then you create a style for your ellipse which includes a DataTrigger, starting the animation you need for your current state.

For example:

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


来源:https://stackoverflow.com/questions/16171422/how-to-make-an-element-reference-a-staticresource-storyboard-in-xaml-instead-of

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!