Can anyone explain to me what I am doing wrong here? I am most certainly a beginner at C# and I do not want to leave it up to XAML when it comes to animating this image on the screen.
_sb = new Storyboard();
DoubleAnimation moveXAnim = new DoubleAnimation();
moveXAnim.Duration = TimeSpan.FromMilliseconds(5000);
moveXAnim.From = 0;
moveXAnim.To = 300;
_sb.Children.Add(moveXAnim);
Storyboard.SetTarget(moveXAnim, Person);
Storyboard.SetTargetProperty(moveXAnim, "(Canvas.Left)");
_sb.Begin();
All the examples I find are XAML.
What makes you think it does not work? I assume that Person is a UIElement.
Is your Person element contained inside a Canvas? The example below should work for your code>
<Canvas>
<TextBlock
Text="Hi"
x:Name="Person" />
</Canvas>
Related
I am trying to use some animations to make my application feel good. But I could not help the choppy animation that no matter what I do, it is always end up stuttering.
Take a look:
DoubleAnimation anim = new DoubleAnimation()
{
//ht is height of DockPanel, I wanted to start from 200 less than Actual DockPanel Height
From = ht - 200,
To = ht,
Duration = TimeSpan.FromSeconds(1),
AccelerationRatio = 0.5,
DecelerationRatio = 0.5
};
x.BeginAnimation(HeightProperty, anim);
//x is the UserControl
Also, what I need to animate is a custom UserControl, which contains some text like 100 words and bunch of Images. I just want to make it grow in to the height of the current DockPanel as soon it is loaded.
What I saw by searching for the solution is this,
Timeline.SetDesiredFrameRate(anim, 10);
Even trying any value in there nothing really happens.
Framerate is like the frame rate of a film.
A low frame rate will give you a choppy film or a choppy animation.
Using a dockpanel is probably a bad idea for some content you are going to animate, because it will try and adjust things every time your height changes.
I suggest you go with a grid instead.
You should use a scaletransform. Partly because as you animate height you will find all the content of your usercontrol have their measures invalidated and they will want to start off the whole measure arrange cycle many times.
If you're thinking measure arrange? Then read up on how the wpf layout system works.
I would also advise you to use xaml rather than code.
Here's some code to think about:
private void StartAnimate_Click(object sender, RoutedEventArgs e)
{
var tran = testRectangle.RenderTransform = new ScaleTransform(1d, 1d)
{
CenterX = 0.5d,
CenterY = 0.5d
};
var anim = new DoubleAnimation
{
To = 1.0,
From=0,
Duration = TimeSpan.FromSeconds(0.5d),
DecelerationRatio = 0.5d,
FillBehavior = FillBehavior.Stop
};
tran.BeginAnimation(
ScaleTransform.ScaleYProperty,
anim,
HandoffBehavior.Compose);
}
I put a rectangle and my button in a dockpanel to prove this works.
<DockPanel>
<Rectangle Fill="Blue" Name="testRectangle"
Width="500"
/>
<Button Content="Animate"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Name="StartAnimate"
Click="StartAnimate_Click" />
</DockPanel>
A rectangle is pretty simple but it animates smoothly.
I have a small button that should adjust vertically and horizontally. I Would like to use Storyboard and manipulate the X and Y under transform.
And I would like to do it code-behind.
The button moves to the correct position, but no animation is active.
private void AnimatePlayerMovement(Player player)
{
//This will hold hour animation
Piece.RenderTransform = new CompositeTransform();
//New storyboard
Storyboard storyboard = new Storyboard();
//New DoubleAnimation - Y
DoubleAnimation translateYAnimation = new DoubleAnimation();
translateYAnimation.From = this.Path[player.from, 1];
translateYAnimation.To = this.Path[player.to, 1];
translateYAnimation.EasingFunction = new ExponentialEase();
translateYAnimation.EasingFunction.EasingMode = EasingMode.EaseOut;
translateYAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
Storyboard.SetTarget(translateYAnimation, Piece);
Storyboard.SetTargetProperty(translateYAnimation,
"(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
storyboard.Children.Add(translateYAnimation);
//New DoubleAnimation - X
DoubleAnimation translateXAnimation = new DoubleAnimation();
translateXAnimation.From = this.Path[player.from, 0];
translateXAnimation.To = this.Path[player.to, 0];
translateXAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
Storyboard.SetTarget(translateXAnimation, Piece);
Storyboard.SetTargetProperty(translateXAnimation,
"(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
storyboard.Children.Add(translateXAnimation);
storyboard.Begin();
}
And the button in xaml
<Button x:Name="Piece" Height="50" Width="50" HorizontalAlignment="Left"
Margin="115,400,0,0" VerticalAlignment="Top" Click="Button_Click"
RenderTransformOrigin="0.5,0.5">
<Button.Template>
<ControlTemplate>
<Image Source="Assets/piece.png"/>
</ControlTemplate>
</Button.Template>
</Button>
I have tested your code and the animation works properly. You can find the working repo on GitHub. As the code is almost 1:1 copy of your sample, except I hardcoded the From and To property values of the animations. Thus I think the problem you are seeing is that this.Path[player.from, 0] and this.Path[player.to, 0] values are the same (or very similar). This way the button jumps to the this.Path[player.from, 0] location and stays there, not moving further.
To learn about animation and UI, I'm making a basic WPF/C# application where a user selects the number of vehicles to display then those vehicles (ie images of different vehicles) appear in the canvas and move around.
The WPF is very simple:
<Grid>
<Canvas x:Name="MenuTabCanvas" Visibility="Visible">
<Label x:Name="AnimateDemo" Content="Animate!" HorizontalAlignment="Left" VerticalAlignment="Top" Width="104" Background="#25A0DA" Foreground="White" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand" MouseDown="AnimateGrid" Canvas.Left="640" Canvas.Top="87"/>
<Canvas x:Name="AnimationCanvas" Canvas.Top="150" Canvas.Left="224" Width="814" Height="489">
</Canvas>
</Grid>
I started with a fade animation using the method described in this post and it works fine. Then I tried the translatetransform as shown below leaving the fade code in comments, and the images appear but nothing moves:
private void AnimateGrid(object sender, EventArgs e)
{
int NumberOfVehicles = 5;
var sb = new Storyboard();
for (int i = 0; i < NumberOfVehicles; i++)
{
//create & add the images to our target canvas
Image Img = getRandomVehicleImage(); //returns image of vehicle
AnimationCanvas.Children.Add(Img);
Canvas.SetTop(Img, 30 + 60 * i); //position image w/in canvas
Canvas.SetLeft(Img, 30 + 80 * i);
//add an animation
DoubleAnimation myAnimation = new DoubleAnimation()
{
// From = 0,
To = 150,
Duration = TimeSpan.FromSeconds(2),
};
Storyboard.SetTarget(myAnimation, Img);
// Storyboard.SetTargetProperty(myAnimation, new PropertyPath(Button.OpacityProperty));
Storyboard.SetTargetProperty(myAnimation, new PropertyPath(TranslateTransform.XProperty));
sb.Children.Add(myAnimation);
}
sb.Begin();
}
I have been able to get it to work with TranslateTransform.BeginAnimation but I would prefer to use the storyboard here.
Why does the translate transform behave differently than the opacity animation and what do I need to do to get it to function as intended?
By default, there is no TranslateTransform applied to a UIElement. So if you want to move an Image, you first have to set its RenderTransform property to a TranslateTransform, and then set the TargetProperty to the correct property path:
Img.RenderTransform = new TranslateTransform();
...
Storyboard.SetTargetProperty(myAnimation, new PropertyPath("RenderTransform.X"));
Alternatively, you could directly animate the TranslateTransform, even without a Storyboard:
var transform = new TranslateTransform();
Img.RenderTransform = transform;
transform.BeginAnimation(TranslateTransform.XProperty, myAnimation);
I have a image in my View, which I want to rotate my image 45 degress when a special event happens. But I keep getting this error all the time:
Cannot resolve all property references in the property path
'RenderTransform.Angle'
What type of property path do I need to set to accomplish this?
var dbAscending = new DoubleAnimation(0, 45, new Duration(TimeSpan.FromMilliseconds(1000)));
var storyboard = new Storyboard();
storyboard.Children.Add(dbAscending);
Storyboard.SetTarget(dbAscending, uc.Cross);
Storyboard.SetTargetProperty(dbAscending, new PropertyPath("RenderTransform.Angle"));
storyboard.Begin();
You would have to assign a RotateTransform to your Image's RenderTransform to make your Storyboard work, e.g. like this:
<Image RenderTransformOrigin="0.5,0.5" ...>
<Image.RenderTransform>
<RotateTransform x:Name="imageRotation"/>
</Image.RenderTransform>
</Image>
Although you could animate this with your Storyboard, it might be easier to just start the animation directly on the RotateTransform object:
var rotationAnimation = new DoubleAnimation(45, TimeSpan.FromSeconds(1));
imageRotation.BeginAnimation(RotateTransform.AngleProperty, rotationAnimation);
A RenderTransform has no Angle property. Make sure there is a RotationTransformation assigned to the RenderTranformation property of the element you are rotating.
new PropertyPath("(UIElement.RenderTransform).(RotateTransform.Angle)"
If you added the Rotation to a TransformGroup the PropertyPath would be (assuming the Rotation is the first child of the group):
new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)"
I have created fade animation for my icon, but when animation finished the icons sets back to alpha 0. How can I get him to stay in 1?
var a = new DoubleAnimation
{
From = 0.0,
To = 1.0,
FillBehavior = FillBehavior.Stop,
Duration = new Duration(TimeSpan.FromSeconds(1))
};
var storyboard = new Storyboard();
storyboard.Children.Add(a);
Storyboard.SetTarget(a, IconGlass);
Storyboard.SetTargetProperty(a, new PropertyPath(OpacityProperty));
storyboard.Begin();
}
XAML:
<StackPanel Name="IconGlass" Orientation="Horizontal" Margin="0,0,0,39" Opacity="0">
this occurs because in your StackPanel you have the Property Opacity set to 0. What you are doing is,
You have a StackPanel with Opacity 0.
You add a Animation to your StackPanel to grow up the opacity.
But after finish the animation, StackPanel will have his default value of Opacity, that is 0.
its not the best way, but you can remove Opacity="0" and Add Visibility="Collapsed"
And when you animation start put your StackPanel Visible.
IconGlass.Visibility = Visibility.Visible;
So when finishing the animation, will no desapear the StackPanel.
Know that this is not the best practise to do, but maybe one of the simplest or fastest way.
I hope this help. greetings!