Search code examples
c#wpfxamlanimationitemtemplate

Different WPF Storyboard Animation in each ListBox.ItemTemplate>DataTemplate


I want to have different animations for each of a ListView item.

<Window.Resources>
    <Storyboard x:Key="myAnimation" RepeatBehavior="Forever">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Duration="0:0:2">
            <DiscreteObjectKeyFrame KeyTime="0:0:0">
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="/img/image1.png"/>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
            <DiscreteObjectKeyFrame KeyTime="0:0:1">
                <DiscreteObjectKeyFrame.Value>
                    <BitmapImage UriSource="/img/image2.png"/>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<ListBox  Name="SessionList" HorizontalContentAlignment="Stretch" >
    <ListBox.ItemTemplate>
        <DataTemplate>
           <Image x:Name="stateimage">
                <Image.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        <BeginStoryboard Storyboard="{StaticResource myAnimation}">
                        </BeginStoryboard>
                    </EventTrigger>
                </Image.Triggers>
            </Image>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The above XAML code works fine for showing the same animation myAnimation for each listitem. But how I can achive it to show different animations (i.e. I have to define several Storyboards in Window.Resources), depending on a Binding Property of the listitem ViewModel?

EDIT:

With the question linked below, I finally got it worked this way. Amazing!

<Window.Resources>
    <Storyboard x:Key="animLOAD" RepeatBehavior="Forever">...</Storyboard>
    <Storyboard x:Key="animPREPARED" RepeatBehavior="Forever">...</Storyboard>
    <Style x:Key="animStyle" TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=st, Mode=OneWay}" Value="LOAD">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource animLOAD}" />
                </DataTrigger.EnterActions>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=st, Mode=OneWay}" Value="PREPARED">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource animPREPARED}" />
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Image Style="{StaticResource animStyle}" /> 

Solution

  • I'm not sure how accessible your model is for this approach but you should be able to use it to some measure. You can use a set of DataTriggers, each inheriting a storyboard:

    <DataTrigger Binding="{Binding Property}" Value="SomeValue">                                            
        <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource Storyboard}"/>
        </DataTrigger.EnterActions>
    </DataTrigger>
    

    I would use them within a ControlTemplate:

    <ControlTemplate TargetType="Image">
        <ControlTemplate.Triggers>
            <!-- DataTriggers -->
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    EDIT:

    This Question has a similar solution, you may not need the ControlTemplate at all.