¿Ancho de animación a ancho real en WPF?
Frecuentes
Visto 3,466 veces
7
¿Cómo puedo animar el ancho de un elemento de 0 a su ancho real en WPF?
Intenté esto:
<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>
Si cambio el enlace a un valor codificado, como 100
, entonces el ancho está correctamente animado, excepto que quiero enlazar con el ancho real del elemento.
Si importa MyElement
es un borde y estoy animando un elemento de pestaña.
Para el registro, esto tampoco funciona:
To="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}"
2 Respuestas
10
Estoy seguro de que esto está mal por MUCHAS razones y no dude en decirme cuántas leyes de WPF he violado, pero... Resolví el mismo problema creando mi propia 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();;
}
}
Ahora soy libre de usar enlaces para las propiedades To From.
<local:BindableDoubleAnimation Storyboard.TargetProperty="Width" From="0" To="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Window}}"/>
Respondido el 12 de junio de 12 a las 12:06
2
Que los enlaces no se puedan usar en animaciones es un problema común.
Una solución sería usar un objeto auxiliar que tenga SourceValue
& TargetValue
(que puedes enlazar a lo que quieras, incluyendo ActualWidth
) a CurrentValue
(que devuelve el valor animado) y un Progress
que se puede animar de 0.0 a 100.0. Cuando se cambia el progreso, solo necesita calcular el CurrentValue
a la que luego puede vincular el Width
de tu objeto. No es bonito, pero debería funcionar.
Respondido el 12 de junio de 12 a las 11:06
No tengo clara esta respuesta. ¿Podría proporcionar un ejemplo de código? ¿Estás describiendo algo similar a la solución de @Andy? - Phillip Scott Givens
@PhillipScottGivens: la respuesta de Andy siempre modifica la animación al crear una capa enlazable encima. Lo que sugiero es diferente, sugiero un objeto intermediario que siempre usa la misma animación que anima su Progress
propiedad de 0
a 100
(por lo tanto, la animación no cambia), este objeto proporciona el valor de la animación a través de un CurrentValue
propiedad que devuelve el valor calculado a partir de su SourceValue
, TargetValue
y Progress
. - media pensión
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas .net wpf xaml animation or haz tu propia pregunta.
¿Alguien ha conseguido que esto funcione para
BindableDoubleAnimation
s que están dentro de unStoryboard
que esta en unVisualState
menosControlTemplate
? Para los casos en los que solo tengo un soloBindableDoubleAnimation
en laVisualState
y codifico el valor "Para" (para decir algo como "100"), nada se anima, y tampocoGetCurrentValueCore
niCreateInstanceCore
están siendo llamados. Para los casos en los que uso el enlace de datos en la propiedad "Para", el enlace siempre falla y siempre genera el error "No se puede encontrar el origen del enlace...". Incluso cuando intento todo desde arriba palabra por palabra, falla. - jason franco... Me encantaría que esto funcione, ¡parece que podría ser una gran solución! - jason franco