Animation width to actual width in WPF?
.net, animation, wpf, xaml
Solution
I'm sure this is wrong for SO many reasons and please feel free to tell me how many WPF laws I've violated but.. I solved the same problem by creating my own BindableDoubleAnimation.
public class BindableDoubleAnimation : DoubleAnimationBase
{
DoubleAnimation internalAnimation;
public DoubleAnimation InternalAnimation { get { return internalAnimation; } }
public double To
{
get { return (double)GetValue(ToProperty); }
set { SetValue(ToProperty, value); }
}
/// <summary>
/// Dependency backing property for the <see cref="To"/> property.
/// </summary>
public static readonly DependencyProperty ToProperty =
DependencyProperty.Register("To", typeof(double), typeof(BindableDoubleAnimation), new UIPropertyMetadata(0d, new PropertyChangedCallback((s, e) =>
{
BindableDoubleAnimation sender = (BindableDoubleAnimation)s;
sender.internalAnimation.To = (double)e.NewValue;
})));
public double From
{
get { return (double)GetValue(FromProperty); }
set { SetValue(FromProperty, value); }
}
/// <summary>
/// Dependency backing property for the <see cref="From"/> property.
/// </summary>
public static readonly DependencyProperty FromProperty =
DependencyProperty.Register("From", typeof(double), typeof(BindableDoubleAnimation), new UIPropertyMetadata(0d, new PropertyChangedCallback((s, e) =>
{
BindableDoubleAnimation sender = (BindableDoubleAnimation)s;
sender.internalAnimation.From = (double)e.NewValue;
})));
public BindableDoubleAnimation()
{
internalAnimation = new DoubleAnimation();
}
protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock)
{
return internalAnimation.GetCurrentValue(defaultOriginValue, defaultDestinationValue, animationClock);
}
protected override Freezable CreateInstanceCore()
{
return internalAnimation.Clone();;
}
}
I'm now free to use bindings for the To From properties.
<local:BindableDoubleAnimation Storyboard.TargetProperty="Width" From="0" To="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Window}}"/>
Problem
How can I animate the width of an element from 0 to its actual width in WPF? I tried this: ``` <ControlTemplate.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:0.3" To="{Binding ElementName=MyElement, Path=ActualWidth}" From="0" Storyboard.TargetProperty="Width" Storyboard.TargetName="MyElement" /> </Storyboard> </BeginStoryboard> </EventTrigger> </ControlTemplate.Triggers> ``` If I change the binding to a hard coded value, like `100`, then the width is properly animated, except that I want to bind to the actual width of the element. If it matters, `MyElement` is a border, and I'm animating a tab item. For the record, this does not work either: ``` To="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}" ```