Cómo: Establecer una propiedad después de animarla con un guión gráfico

En algunos casos puede parecer que no es posible cambiar el valor de una propiedad después de haberla animado.

Animar el color de un SolidColorBrush

En el ejemplo siguiente se usa Storyboard para animar el color de SolidColorBrush. El guion gráfico se desencadena cuando se hace clic en el botón. El evento Completed se controla para que se notifique al programa el momento en que ColorAnimation se completa.

<Button
  Content="Animate and Then Set Example 1">
  <Button.Background>
    <SolidColorBrush x:Name="Button1BackgroundBrush"
      Color="Red" />
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation
            Storyboard.TargetName="Button1BackgroundBrush"
            Storyboard.TargetProperty="Color"
            From="Red" To="Yellow" Duration="0:0:5"
            FillBehavior="HoldEnd"
            Completed="setButton1BackgroundBrushColor" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Cambiar el color del pincel

Una vez completado ColorAnimation, el programa intenta cambiar el color del pincel a azul.

private void setButton1BackgroundBrushColor(object sender, EventArgs e)
{

    // Does not appear to have any effect:
    // the brush remains yellow.
    Button1BackgroundBrush.Color = Colors.Blue;
}
Private Sub setButton1BackgroundBrushColor(ByVal sender As Object, ByVal e As EventArgs)

    ' Does not appear to have any effect:
    ' the brush remains yellow.
    Button1BackgroundBrush.Color = Colors.Blue
End Sub

El código anterior no parece hacer nada: el pincel permanece amarillo, que es el valor proporcionado por el ColorAnimation que ha animado el pincel. En realidad, el valor de propiedad subyacente (el valor base) se ha cambiado a azul. Sin embargo, el valor efectivo, o actual, permanece amarillo porque ColorAnimation sigue reemplazando al valor base. Si desea que el valor base vuelva a ser el valor efectivo, debe impedir que la animación influya en la propiedad. Hay tres maneras de hacerlo con animaciones de guion gráfico:

  • Establecer la propiedad FillBehavior de la animación en Stop

  • Quite todo el guion gráfico.

  • Quite la animación de la propiedad individual.

Establecer la propiedad FillBehavior de la animación en Detener

Al establecer FillBehavior en Stop, está indicando a la animación que debe dejar de afectar a su propiedad de destino después de que llegue al final de su periodo activo.

<Button
  Content="Animate and Then Set Example 2">
  <Button.Background>
    <SolidColorBrush x:Name="Button2BackgroundBrush"
      Color="Red" />
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation
            Storyboard.TargetName="Button2BackgroundBrush"
            Storyboard.TargetProperty="Color"
            From="Red" To="Yellow" Duration="0:0:5"
            FillBehavior="Stop"
            Completed="setButton2BackgroundBrushColor" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>
private void setButton2BackgroundBrushColor(object sender, EventArgs e)
{

    // This appears to work:
    // the brush changes to blue.
    Button2BackgroundBrush.Color = Colors.Blue;
}
Private Sub setButton2BackgroundBrushColor(ByVal sender As Object, ByVal e As EventArgs)

    ' This appears to work:
    ' the brush changes to blue.
    Button2BackgroundBrush.Color = Colors.Blue
End Sub

Quitar todo el guion gráfico

Mediante el uso de un desencadenador RemoveStoryboard o el método Storyboard.Remove, se indica a las animaciones del guion gráfico que deben dejar de afectar a sus propiedades de destino. La diferencia entre este enfoque y establecer la propiedad FillBehavior es que se puede quitar el guion gráfico en cualquier momento, mientras que la propiedad FillBehavior solo tiene efecto cuando la animación alcanza el final de su periodo activo.

<Button
  Name="Button3"
  Content="Animate and Then Set Example 3">
  <Button.Background>
    <SolidColorBrush x:Name="Button3BackgroundBrush"
      Color="Red" />
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard Name="MyBeginStoryboard">
        <Storyboard x:Name="MyStoryboard">
          <ColorAnimation
            Storyboard.TargetName="Button3BackgroundBrush"
            Storyboard.TargetProperty="Color"
            From="Red" To="Yellow" Duration="0:0:5"
            FillBehavior="HoldEnd"
            Completed="setButton3BackgroundBrushColor" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>
private void setButton3BackgroundBrushColor(object sender, EventArgs e)
{

     // This appears to work:
    // the brush changes to blue.
    MyStoryboard.Remove(Button3);
    Button3BackgroundBrush.Color = Colors.Blue;
}
Private Sub setButton3BackgroundBrushColor(ByVal sender As Object, ByVal e As EventArgs)

     ' This appears to work:
    ' the brush changes to blue.
    MyStoryboard.Remove(Button3)
    Button3BackgroundBrush.Color = Colors.Blue
End Sub

Quitar una animación de una propiedad individual

Otra técnica para impedir que una animación afecte a una propiedad es usar el método BeginAnimation(DependencyProperty, AnimationTimeline) del objeto que se está animando. Especifique la propiedad que se va a animar como primer parámetro y null, como segundo parámetro.

<Button
  Name="Button4"
  Content="Animate and Then Set Example 4">
  <Button.Background>
    <SolidColorBrush x:Name="Button4BackgroundBrush"
      Color="Red" />
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation
            Storyboard.TargetName="Button4BackgroundBrush"
            Storyboard.TargetProperty="Color"
            From="Red" To="Yellow" Duration="0:0:5"
            FillBehavior="HoldEnd"
            Completed="setButton4BackgroundBrushColor" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>
private void setButton4BackgroundBrushColor(object sender, EventArgs e)
{

     // This appears to work:
    // the brush changes to blue.
    Button4BackgroundBrush.BeginAnimation(SolidColorBrush.ColorProperty, null);
    Button4BackgroundBrush.Color = Colors.Blue;
}
Private Sub setButton4BackgroundBrushColor(ByVal sender As Object, ByVal e As EventArgs)

     ' This appears to work:
    ' the brush changes to blue.
    Button4BackgroundBrush.BeginAnimation(SolidColorBrush.ColorProperty, Nothing)
    Button4BackgroundBrush.Color = Colors.Blue
End Sub

Esta técnica también funciona para animaciones que no son de guion gráfico.

Vea también