Cannot create an animation in code-behind
It's great that you can set up animations in your XAML file. However I have a situation where I want to set up an animation in the code-behind.
In my code I have a scrollviewer because not all content fits on the screen. If an item is made 'active' (from code behind), I want this scrollviewer to smoothly scroll towards this item. It is important that this is a smooth animation. I tried to do this using this code:
Unfortunately the 'BeginAnimation' method from WPF is not present in NoesisGUI.
Is there some workaround so I can set up an animation from code-behind?
In my code I have a scrollviewer because not all content fits on the screen. If an item is made 'active' (from code behind), I want this scrollviewer to smoothly scroll towards this item. It is important that this is a smooth animation. I tried to do this using this code:
Code: Select all
DoubleAnimation anim = new DoubleAnimation();
anim.SetFrom(new Noesis.NullableFloat(scrollViewer.GetHorizontalOffset()));
anim.SetTo(new Noesis.NullableFloat(_scrollViewerGoal));
anim.SetDuration(new Duration(new Noesis.TimeSpan(0.5)));
scrollViewer.BeginAnimation(ScrollViewer.HorizontalOffsetProperty, anim);
Is there some workaround so I can set up an animation from code-behind?
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Cannot create an animation in code-behind
You are right, BeginAnimation is not yet supported. We add it to our feature list for a future update.
Meanwhile you can create a Storyboard and play it:
Meanwhile you can create a Storyboard and play it:
Code: Select all
DoubleAnimation anim = new DoubleAnimation();
anim.SetFrom(new Noesis.NullableFloat(scrollViewer.GetHorizontalOffset()));
anim.SetTo(new Noesis.NullableFloat(_scrollViewerGoal));
anim.SetDuration(new Duration(new Noesis.TimeSpan(0.5)));
Storyboard.SetTarget(anim, scrollViewer);
Storyboard.SetTargetProperty(anim, new PropertyPath(ScrollViewer.HorizontalOffsetProperty));
Storyboard storyboard = new Storyboard();
storyboard.GetChildren().Add(anim);
storyboard.Begin(scrollViewer);
Re: Cannot create an animation in code-behind
Somewhat related, I am having trouble animating the transform of an object programmatically, not in a code behind but just in my game. I am using the native library. I have Canvas which I can move by setting its RenderTransform to a new TranslateTransform but I can't seem to figure out how to animate the translation. Do you know how I might accomplish this?
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Cannot create an animation in code-behind
You can create a complete Storyboard from code (as explained before) or you can design the animation in Blend, assign names to the required KeyFrames or Animations, modify the desired values and Begin the animation from code.Somewhat related, I am having trouble animating the transform of an object programmatically, not in a code behind but just in my game. I am using the native library. I have Canvas which I can move by setting its RenderTransform to a new TranslateTransform but I can't seem to figure out how to animate the translation. Do you know how I might accomplish this?
If you want to animate the translation of an element, that element should define the proper Transform element first:
Code: Select all
<Canvas x:Name="MyCanvas" RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<TranslateTransform />
</Canvas.RenderTransform>
</Canvas>
Code: Select all
<Storyboard x:Key="MoveCanvas">
<DoubleAnimation
Storyboard.TargetElement="MyCanvas"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
Durantion="0:0:1" To="200"/>
</Storyboard>
Code: Select all
DoubleAnimation anim = new DoubleAnimation();
anim.SetTo(new Noesis.NullableFloat(200.0f));
anim.SetDuration(new Duration(new Noesis.TimeSpan(1)));
Storyboard.SetTarget(anim, myCanvas);
Storyboard.SetTargetProperty(anim, new PropertyPath(
"(UIElement.RenderTransform).(TranslateTransform.X)"));
Storyboard storyboard = new Storyboard();
storyboard.GetChildren().Add(anim);
storyboard.Begin(myCanvas);
Re: Cannot create an animation in code-behind
Thanks for your response. I have the animation set up but when I play it I do not see the canvas move and I am unsure why.
The canvas in xaml is defined as:
In code I have:
I added a delegate for the storyboard completion and that gets called at the appropriate time so the animation is updating/completing.
Also if I just set the transform of the canvas directly to my end point it shows up in the correct spot.
The canvas in xaml is defined as:
Code: Select all
<Canvas x:Name="difficultyring" RenderTransformOrigin="0.5,0.5" Height="307.824" Canvas.Left="-15.307" Canvas.Top="15.111" Width="203.852" d:IsHidden="True">
<Canvas.RenderTransform>
<TranslateTransform />
</Canvas.RenderTransform>
<Rectangle Fill="{StaticResource difficultyring}" Stretch="Fill" Height="203.852" Width="203.852" />
</Canvas>
Code: Select all
Noesis::Gui::Nullable<NsFloat32> endPoint = m_difficulty * m_distanceBetweenRatingBackgrounds;
NsFloat64 time = 0.5;
Noesis::Gui::TimeSpan timeSpan(time);
Noesis::Gui::Duration duration(timeSpan);
Noesis::Gui::DoubleAnimation* pAnim = new Noesis::Gui::DoubleAnimation();
pAnim->SetTo(endPoint);
pAnim->SetDuration(duration);
Storyboard::SetTarget(pAnim, m_pDifficultyRing);
Storyboard::SetTargetProperty(pAnim, new Noesis::Gui::PropertyPath(Noesis::Gui::TranslateTransform::XProperty));
Noesis::Gui::Storyboard* pStoryboard = new Noesis::Gui::Storyboard();
pStoryboard->GetChildren()->Add(pAnim);
pStoryboard->Begin(m_pDifficultyRing);
Also if I just set the transform of the canvas directly to my end point it shows up in the correct spot.
-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Cannot create an animation in code-behind
There is something wrong in your code.
The PropertyPath is pointing to the TranslateTransform::XProperty, but the Target (the Canvas) does not contain this property. You have to use a chained property path as I specified in my previous post (this is what Blend generates when you animate that property):
Or you can simplify the path if property owner is not specified (both codes are equivalent):
You have to reach the RenderTransform of the Canvas first, then the X property of the TranslateTransform.
It should work if you change your code like this.
P.S. Pay attention to the creation of objects, because they are created with 1 reference. If you don't use Ptr, you should Release() your reference after transferring the ownership of the object to another entity. Otherwise you will be leaking memory. But I recommend you to use Ptr with the *new constructor (as I did in the previous code with the PropertyPath) to track object references automatically.
The PropertyPath is pointing to the TranslateTransform::XProperty, but the Target (the Canvas) does not contain this property. You have to use a chained property path as I specified in my previous post (this is what Blend generates when you animate that property):
Code: Select all
...
Storyboard::SetTarget(pAnim, m_pDifficultyRing);
Ptr<PropertyPath> path = *new Noesis::Gui::PropertyPath(
"(UIElement.RenderTransform).(TranslateTransform.X)");
Storyboard::SetTargetProperty(pAnim, path.GetPtr());
...
Code: Select all
...
Storyboard::SetTarget(pAnim, m_pDifficultyRing);
Ptr<PropertyPath> path = *new Noesis::Gui::PropertyPath("RenderTransform.X");
Storyboard::SetTargetProperty(pAnim, path.GetPtr());
...
It should work if you change your code like this.
P.S. Pay attention to the creation of objects, because they are created with 1 reference. If you don't use Ptr, you should Release() your reference after transferring the ownership of the object to another entity. Otherwise you will be leaking memory. But I recommend you to use Ptr with the *new constructor (as I did in the previous code with the PropertyPath) to track object references automatically.
Re: Cannot create an animation in code-behind
I've tried to animate ScrollViewer.HorizontalOffsetProperty using Storyboard, and it just don't work 
I've copied the example by sfernandez posted on 03 Jul 2014, 22:55 here, and it seems it's not working (with 1.1.14 at least). Please either confirm that it's not supported, or provide a working example

I've copied the example by sfernandez posted on 03 Jul 2014, 22:55 here, and it seems it's not working (with 1.1.14 at least). Please either confirm that it's not supported, or provide a working example

-
-
sfernandez
Site Admin
- Posts: 3222
- Joined:
Re: Cannot create an animation in code-behind
Hi, sorry for the very late answer on these holidays.I've tried to animate ScrollViewer.HorizontalOffsetProperty using Storyboard, and it just don't work
I've copied the example by sfernandez posted on 03 Jul 2014, 22:55 here, and it seems it's not working (with 1.1.14 at least). Please either confirm that it's not supported, or provide a working example
Both ScrollViewer's HorizontalOffset and VerticalOffset properties are read-only, so you cannot animate them directly. What you can do is use an attached property to indirectly animate them by calling ScrollToHorizontalOffset() or ScrollToVerticalOffset():
Code: Select all
namespace Animation
{
[Extended]
public class Extensions : BaseComponent
{
public static DependencyProperty VerticalScrollProperty = DependencyProperty.Register(
"VerticalScroll", typeof(float), typeof(Extensions),
new PropertyMetadata(0.0f, Extensions.OnVerticalOffsetChanged));
public static float GetVerticalOffset(DependencyObject d)
{
return d.GetValue<float>(VerticalScrollProperty);
}
public static void SetVerticalOffset(DependencyObject d, float offset)
{
d.SetValue<float>(VerticalScrollProperty, offset);
}
static void OnVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ScrollViewer scroll = d.As<ScrollViewer>();
if (scroll != null)
{
float offset = scroll.GetValue<float>(VerticalScrollProperty);
scroll.ScrollToVerticalOffset(offset);
}
}
}
}
Code: Select all
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Animation">
<Grid.Resources>
<Storyboard x:Key="anim" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="scroll" Storyboard.TargetProperty="(local:Extensions.VerticalScroll)"
Duration="0:0:2" From="0" To="100"/>
</Storyboard>
</Grid.Resources>
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource anim}"/>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Border BorderBrush="Silver" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<ScrollViewer x:Name="scroll" Width="200" Height="200"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<Ellipse Fill="Blue" Width="300" Height="400"/>
</ScrollViewer>
</Border>
</Grid>
Who is online
Users browsing this forum: Google [Bot] and 3 guests