peter
peter

Reputation: 2113

Bind animations to ViewModel property

I've got a "flip card"-style animation that works just fine. On one side, it has a button that, when clicked, triggers the animation "FlipOpen":

<Button Content="click me" Height="130">
<Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click" >
        <BeginStoryboard  Storyboard="{StaticResource FlipOpen}">
        </BeginStoryboard>
    </EventTrigger>
</Button.Triggers>

    <Storyboard x:Key="FlipOpen">
        <DoubleAnimation Duration="00:00:0.5" Storyboard.TargetProperty="RenderTransform.ScaleX" From="-1" To="1" Storyboard.TargetName="Back"/>
        <DoubleAnimation Duration="00:00:0.5" Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="-1" Storyboard.TargetName="Front"/>
    </Storyboard>

    <Storyboard x:Key="FlipClose">
        <DoubleAnimation Duration="00:00:0.5" Storyboard.TargetProperty="RenderTransform.ScaleX" From="1" To="-1" Storyboard.TargetName="Back"/>
        <DoubleAnimation Duration="00:00:0.5" Storyboard.TargetProperty="RenderTransform.ScaleX" From="-1" To="1" Storyboard.TargetName="Front"/>
    </Storyboard>

I would like to bind the animation to a boolean property on my ViewModel and I have tried to use DataTriggers:

a) define a style:

<Style x:Key="myStyle">
<Style.Triggers>
    <DataTrigger Binding="{Binding FlipTheCard}" Value="true">
        <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource FlipOpen}"/>
        </DataTrigger.EnterActions>
    </DataTrigger>
    <DataTrigger Binding="{Binding FlipTheCard}" Value="false">
        <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource FlipClose}"/>
        </DataTrigger.EnterActions>
    </DataTrigger>
</Style.Triggers>

b) apply it to both Grid-Containers that contain the front and back:

<Grid RenderTransformOrigin="0.5,0.5" x:Name="Back" Opacity="0" Style="{StaticResource myStyle}">
...
</Grid>

c) don't start the animation on button click, but bind a command that toggles the boolean to the button:

<Button Content="click me!" Command="{Binding ToggleFlipCard}" Height="130">

However, this results in an exception ("A storyboard-structure within a Style can not have a TargetName. Remove the TargetName").

What am I doing wrong here? How can I bind these animations to a boolean property on my ViewModel?

Thank you for any help!

Upvotes: 0

Views: 1278

Answers (2)

Staeff
Staeff

Reputation: 5084

I've also found a solution...it's far from perfect on the animation side (as I don't use keyframes and just scale the x property of both at the same time) but it should give you the idea:

Style:

<Storyboard x:Key="FlipOpen">
    <DoubleAnimation Duration="0:0:0.3"
        Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleX)"
        To="0" />
</Storyboard>
<Storyboard x:Key="FlipClose">
    <DoubleAnimation Duration="0:0:0.3"
         Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleX)"
         From="0"
         To="1" />
</Storyboard>

<Style x:Key="GridStyle" TargetType="Grid">
    <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
    <Setter Property="RenderTransform">
        <Setter.Value>
            <ScaleTransform ScaleX="1" ScaleY="1" />
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="FrontGridStyle" TargetType="Grid"
        BasedOn="{StaticResource GridStyle}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding FlipTheCard}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource FlipOpen}" />
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource FlipClose}" />
            </DataTrigger.ExitActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

<Style x:Key="BackGridStyle" TargetType="Grid"
    BasedOn="{StaticResource GridStyle}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding FlipTheCard}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource FlipClose}" />
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource FlipOpen}" />
            </DataTrigger.ExitActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Grid:

<Grid>
    <Grid Style="{StaticResource FrontGridStyle}">
        <Border Width="100"
                Height="100"
                Background="Red" />
        <Button HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Command="{Binding ToggleFlipCard}"
                Content="click me!" />
    </Grid>

    <Grid Style="{StaticResource BackGridStyle}">
        <Border Width="100"
                Height="100"
                Background="Green" />
        <Button HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Command="{Binding ToggleFlipCard}"
                Content="click me!" />
    </Grid>
</Grid>

Upvotes: 1

peter
peter

Reputation: 2113

I found a solution.. yikes

  • reference Microsoft.Expression.Interactions.dll
  • define Interaction-Triggers:

        <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding FlipToFront}" Value="true">
            <ei:ControlStoryboardAction Storyboard="{StaticResource FlipOpen}"/>
        </ei:DataTrigger>
        <ei:DataTrigger Binding="{Binding FlipToFront}" Value="false">
            <ei:ControlStoryboardAction Storyboard="{StaticResource FlipClose}"/>
        </ei:DataTrigger>
    </i:Interaction.Triggers>
    

credits

Upvotes: 0

Related Questions