How to animate Margin property in WPF
Solution 1
Margin
property can be animated using ThicknessAnimation
<Storyboard >
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" BeginTime="00:00:00">
<SplineThicknessKeyFrame KeyTime="00:00:00" Value="134, 70,0,0" />
<SplineThicknessKeyFrame KeyTime="00:00:03" Value="50, 70,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
Solution 2
Actually, ya you can do what you want to do, exactly as you want to do using RenderTransform
mixed with some DoubleAnimation
and even add some extra flair to it, for example;
<Grid x:Name="TheObject" Opacity="0">
<Grid.RenderTransform>
<TranslateTransform x:Name="MoveMeBaby" X="50" />
</Grid.RenderTransform>
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MoveMeBaby"
Storyboard.TargetProperty="X">
<SplineDoubleKeyFrame KeyTime="0:0:1.25" Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="TheObject"
Storyboard.TargetProperty="Opacity">
<SplineDoubleKeyFrame KeyTime="0:0:1.55" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
Will move that object 50px on the X axis and even fade it in while it does so. Give it a shot and play with the values of the X
property and the KeyTime
to get what you want. Hope this helps, cheers.
Solution 3
You can't animate Margin.Left (because Left
is not a dependency property), but you can animate Margin
. Use ObjectAnimationUsingKeyFrames
:
<Storyboard x:Key="MoveMe">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="GroupTileSecond"
Storyboard.TargetProperty="Margin">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Thickness>134,70,0,0</Thickness>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:03">
<DiscreteObjectKeyFrame.Value>
<Thickness>50,70,0,0</Thickness>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
There are some alternatives that allow you to use a DoubleAnimation
, rather than key frames:
- Place your target inside a Canvas, and animate its x position using
Canvas.Left
. - Apply a
TranslateTransform
to your target, and animate its x position usingTranslateTransform.X
.
Solution 4
As an alternative answer @McGarnagle
you can use animation for HorizontalAlignment
and VerticalAlignment
properties.
Example:
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GroupTileSecond"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
Solution 5
i just created a animation. code bellow
using System;
using System.Windows;
using System.Windows.Media.Animation;
namespace ImagesSwitcher
{
class MarginAnimation : AnimationTimeline
{
protected override Freezable CreateInstanceCore()
{
return new MarginAnimation();
}
public override Type TargetPropertyType => typeof(Thickness);
private double GetContrast(double dTo,double dFrom,double process)
{
if (dTo < dFrom)
{
return dTo + (1 - process) * (dFrom - dTo);
}
return dFrom + (dTo - dFrom) * process;
}
public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
{
if (!From.HasValue || !To.HasValue || animationClock.CurrentProgress == null) return null;
var progress = animationClock.CurrentProgress.Value;
if (progress.Equals(0)) return null;
if (progress.Equals(1)) return To.Value;
var fromValue = From.Value;
var toValue = To.Value;
var l = GetContrast(toValue.Left ,fromValue.Left, progress);
var t = GetContrast(toValue.Top, fromValue.Top, progress);
var r = GetContrast(toValue.Right, fromValue.Right, progress);
var b = GetContrast(toValue.Bottom, fromValue.Bottom, progress);
return new Thickness(l,t,r,b);
}
public Thickness? To
{
set => SetValue(ToProperty, value);
get => (Thickness)GetValue(ToProperty);
}
public static DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(Thickness), typeof(MarginAnimation), new PropertyMetadata(null));
public Thickness? From
{
set => SetValue(FromProperty, value);
get => (Thickness)GetValue(FromProperty);
}
public static DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(Thickness), typeof(MarginAnimation), new PropertyMetadata(null));
}
}
Gaja Kannan
Updated on August 08, 2022Comments
-
Gaja Kannan almost 2 years
I want to move animate an rectangle object to move it in x-axis. I am new to WPF animation, started out with the following:
<Storyboard x:Key="MoveMe"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GroupTileSecond" Storyboard.TargetProperty="(**Margin.Left**)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="**134, 70,0,0**" /> <SplineDoubleKeyFrame KeyTime="00:00:03" Value="**50, 70,0,0**" /> </DoubleAnimationUsingKeyFrames> </Storyboard>
Obviously found out that I cant use
Margin.Left
asStoryboard.TargetProperty
or use134,70,0,0
in Value property.So, how do I move an object in XAML WPF.
-
Chris W. over 10 years@McGarnagle & AnatoliyNikolaev - +1 to both you guys too, got to love when 3 guys can figure out different ways to screw in a light bulb :)
-
Chris W. over 10 yearsHah! another +1, forgot about the Thickness too
-
Chris W. over 10 yearsStill, I just dig the fact you put a problem in front of some guys and each one has a different clever way. That alone is awesome, great show for the OP's first post, I love fun one's like these. Cheers!
-
Gaja Kannan over 10 yearsI got following error Exception "{"Cannot animate the 'Margin' property on a 'System.Windows.Shapes.Rectangle' using a 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames'. For details see the inner exception."}" InnerException "{"The animation(s) applied to the 'Margin' property calculate a current value of '134,70,0,0', which is not a valid value for the property."}"
-
Gaja Kannan over 10 yearsWorked like a charm. Thanks!
-
McGarnagle over 10 years@GajaKannan hm ... try specifying the Thickness explicitly, as in my edit above.