Home > Software design >  WPF Animation - Rotate elements on button click
WPF Animation - Rotate elements on button click

Time:11-23

I want to rotate two elements from 0 to angles: 1. Element (ClampL) 45 angle and 2. Element (ClampR) -45 Angle, but they should move together. The elements are 2 clamps which are open and when they grab something, they close and this process should happen on button click.

Here is my XAML:

<UserControl x:Class="WPF_AnimatedLift.View.Prozess"
             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:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPF_AnimatedLift.View" xmlns:viewmodel="clr-namespace:WPF_AnimatedLift.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="1000">
    



    <Canvas x:Name="canvas" Margin="0,0,-163,-83">

        

        <Path x:Name="ClampR" Fill="#FF000000" StrokeThickness="2.12787" Data="M 524.2207 473.57227 L 524.2207 563.57227 L 137.14258 563.57227 L 137.14258 652.14258 L 571.42773 652.14258 L 571.42773 563.57227 L 571.36328 563.57227 L 571.36328 473.57227 L 524.2207 473.57227 z " Height="68.668" Stretch="Fill" Width="80.734" Canvas.Left="411.375" Canvas.Top="339.125" >
            <Path.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="ClampR"
                                Storyboard.TargetProperty="LayoutTransform.(RotateTransform.Angle)"
                                From="0"
                                To="360"
                                Duration="0:0:5"
                                RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Path.Triggers>
            <Path.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform ScaleY="0.265" ScaleX="0.265"/>
                    <SkewTransform/>
                    <RotateTransform CenterX="0.5" CenterY="0.5" Angle="-45"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Path.LayoutTransform>
        </Path>

        <Path x:Name="ClampL" Fill="#FF000000" StrokeThickness="2.12787" Data="M 110 344.28516 L 110 434.28516 L 110 485.71484 L 110 522.85742 L 544.28516 522.85742 L 544.28516 434.28516 L 157.14258 434.28516 L 157.14258 344.28516 L 110 344.28516 z " Height="68.668" Stretch="Fill" Width="80.734" Canvas.Left="384.508" Canvas.Top="339.166">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleY="0.265" ScaleX="0.265"/>
                    <SkewTransform/>
                    <RotateTransform Angle="45"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Path.RenderTransform>
        </Path>


        <Button Content="START" Canvas.Left="84" Canvas.Top="403" Width="106" Height="48" FontSize="30" FontWeight="Bold" Name="BtnStart" Command="{Binding ClickCommand, UpdateSourceTrigger=PropertyChanged}" >
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click"> //???
                    <BeginStoryboard Storyboard="{StaticResource Storyboard}" />
                </EventTrigger>
            </Button.Triggers>
        </Button>

    </Canvas>
    <UserControl.DataContext>
        <viewmodel:ProzessViewModel/>
    </UserControl.DataContext>
</UserControl>

As you can see in code, I tried with Path.Trigger, DoubleAnimation, but it doesn't work, can someone help me?

Thank you.

CodePudding user response:

Basically, in EventTrigger, you can only refer the elements that exist inside that FrameworkElement. The solution would be different depending on where you want to set EventTrigger.

1. Button

You can use EventTrigger in the Button, which is the source of Button.Click event, like the following. The elements are simplified to a minimum for brevity and the Storyboard.TargetProperty is modified to circumvent TransformGroup.

<Canvas x:Name="canvas">
    <Path x:Name="ClampR"
          Canvas.Left="411" Canvas.Top="339"
          Width="80" Height="68"
          Fill="Black"
          Data="M 0,0 1,0 0,1 z" Stretch="Fill">
        <Path.LayoutTransform>
            <TransformGroup>
                <ScaleTransform ScaleY="0.265" ScaleX="0.265"/>
                <SkewTransform/>
                <RotateTransform CenterX="0.5" CenterY="0.5" Angle="-45"/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.LayoutTransform>
    </Path>

    <Button x:Name="BtnStart"
            Canvas.Left="84" Canvas.Top="403"
            Width="106" Height="48"
            Content="START">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation
                            Storyboard.TargetName="ClampR"
                            Storyboard.TargetProperty="LayoutTransform.Children[2].Angle"
                            From="0" To="360"
                            Duration="0:0:5"
                            RepeatBehavior="Forever"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>
</Canvas>

2. Canvas

As Button.Click is RoutedEvent and propagated to the root, you can use EventTrigger at parent level. In this case, at Canvas.Triggers.

<Canvas x:Name="canvas">
    <Canvas.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="ClampR"
                        Storyboard.TargetProperty="LayoutTransform.Children[2].Angle"
                        From="0" To="360"
                        Duration="0:0:5"
                        RepeatBehavior="Forever"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Canvas.Triggers>

    <Path x:Name="ClampR"
          Canvas.Left="411" Canvas.Top="339"
          Width="80" Height="68"
          Fill="Black"
          Data="M 0,0 1,0 0,1 z" Stretch="Fill">
        <Path.LayoutTransform>
            <TransformGroup>
                <ScaleTransform ScaleY="0.265" ScaleX="0.265"/>
                <SkewTransform/>
                <RotateTransform CenterX="0.5" CenterY="0.5" Angle="-45"/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.LayoutTransform>
    </Path>

    <Button x:Name="BtnStart"
            Canvas.Left="84" Canvas.Top="403"
            Width="106" Height="48"
            Content="START"/>
</Canvas>

3. Path

Unlike standard EventTrigger, EventTrigger of Microsoft.Xaml.Behaviors.Wpf is more robust and can refer other controls. Thus it can work in the Path.

Add xmlns:i="http://schemas.microsoft.com/xaml/behaviors" in header.

<Canvas x:Name="canvas">
    <Path x:Name="ClampR"
          Canvas.Left="411" Canvas.Top="339"
          Width="80" Height="68"
          Fill="Black"
          Data="M 0,0 1,0 0,1 z" Stretch="Fill">
        <i:Interaction.Triggers>
            <i:EventTrigger SourceName="BtnStart" EventName="Click">
                <i:ControlStoryboardAction>
                    <i:ControlStoryboardAction.Storyboard>
                        <Storyboard>
                            <DoubleAnimation
                                Storyboard.TargetName="Rotation"
                                Storyboard.TargetProperty="(RotateTransform.Angle)"
                                From="0" To="360"
                                Duration="0:0:5"
                                RepeatBehavior="Forever"/>
                        </Storyboard>
                    </i:ControlStoryboardAction.Storyboard>
                </i:ControlStoryboardAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <Path.LayoutTransform>
            <TransformGroup>
                <ScaleTransform ScaleY="0.265" ScaleX="0.265"/>
                <SkewTransform/>
                <RotateTransform x:Name="Rotation" CenterX="0.5" CenterY="0.5" Angle="-45"/>
                <TranslateTransform/>
            </TransformGroup>
        </Path.LayoutTransform>
    </Path>

    <Button x:Name="BtnStart"
            Canvas.Left="84" Canvas.Top="403"
            Width="106" Height="48"
            Content="START"/>
</Canvas>
  • Related