Question

Overflow!

I would like to program a variable Animation for WP.

I created Animation with Expression Blend like this:

<Storyboard x:Name="rotateC">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="currentDeviancePointer_s">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="10"/>
        </DoubleAnimationUsingKeyFrames>
</Storyboard>

Now i would like to bind second value to a variable.

I found tutorials for Dependency Properties and tried them out. My code compiles and runs, but nothing happens :(

Here is what i have done:

Created dependency object:

  public class RotateClass : DependencyObject
  {
    public static readonly DependencyProperty NewAngleProperty =
        DependencyProperty.Register("newAngle", typeof(double), typeof(RotateClass), new PropertyMetadata(10.0));

    public double newAngle
    {
        get
        {
            return (double)GetValue(NewAngleProperty);
        }
        set
        {
            SetValue(NewAngleProperty, (double)value);
        }
    }
}

Created one object:

    public MainPage()
    {
        InitializeComponent();

        ...

        angleContainer= new RotateClass();

        ...
    }

I created a button with following handler:

angleContainer.newAngle = 45;


if (rotateC.GetCurrentState() != ClockState.Active)
{
     rotateC.Begin();
}

And here is my binding:

<Storyboard x:Name="rotateC">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="currentDeviancePointer_s">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="{Binding ElementName=angleContainer,Path=newAngle}"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

Is there any mistake?

Maybe i am doing this in the too difficult way? Is there any other solution? Thank you for your help!

Was it helpful?

Solution

Ok, assuming your rotation is defined like this:

<Window.Resources>
  ...
  <Storyboard x:Key="RotateC">
    <DoubleAnimationUsingKeyFrames 
        Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)" 
        Storyboard.TargetName="currentDeviancePointer_s">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="{Binding ValueToRotate}"/>
    </DoubleAnimationUsingKeyFrames>
  </Storyboard>
</Window.Resources>

First, note that you need the x:Key here, not the name. This goes in your window or usercontrol resources, before the root element. Second, notice that I'm binding the value to ValueToRotate. This will be a DependencyProperty that you'll attach to.
I've also set the Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle), so it'll change the angle of the element.

You need to have an element with the name currentDeviancePointer_s since this is what you have in the Storyboard.TargetName. Let's assume you have a Label defined:

<Label Name="currentDeviancePointer_s" .../>

Now your storyboard points to that label (via the Storyboard.TargetName)

Create your dependency property:

public static readonly DependencyProperty RotateToValueProperty =
        DependencyProperty.Register("RotateToValue", typeof (double), typeof (MainWindow), new PropertyMetadata(default(double)));

    public double RotateToValue
    {
        get { return (double)GetValue(RotateToValueProperty); }
        set { SetValue(RotateToValueProperty, value); }
    }

Feel free to initialize it in the ctor, or bind it to a different element or whatever you want to do ...

public MainWindow()
{
    InitializeComponent();
    ...
    RotateToValue = 45;
        ...
}

Assuming this is your button:

<Button Content="Lets rotate something">
  <Button.Triggers>
    <EventTrigger RoutedEvent="ButtonBase.Click">
      <BeginStoryboard Storyboard="{Binding Source={StaticResource RotateC}}"/>
    </EventTrigger>
  </Button.Triggers>
</Button>

You can see it has a triger than once the button is clicked, will set the Storyboard we defined in the resource in motion.
That Storyboard is targeting the Label (change the element to whatever you want, just make sure your storyboard is pointing to the right element), and you'll see it rotating 45 degrees in our case (since we set the RotateToValue to 45.

Done :).

Edit: If you insist on using the begin: 1. Make sure you're window has a name:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="Window_name_here">

You don't need the name on your Storyboard, the x:Key is enough. I'm assuming it's still RotateC

On your code behind, use this inside a different button click (so you can see it working):

((Storyboard)Window_name_here.Resources["RotateC"]).Begin();

OTHER TIPS

Everything that Noctis said was correct! The only forgotten Thing was:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

Now it works!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top