Pergunta

Como posso remover um storyboard no xaml (ou seja, a ação removora em um datatrigger), mas mantenha o valor que foi animado. Semelhante ao Animative.Beginanimation:

Se o início da animação for nulo, quaisquer animações atuais serão removidas e o valor atual da propriedade será mantido.

Foi útil?

Solução

O uso principal do Removestoryboard é remover os valores animados e colocá-los de volta ao seu estado não animado. Na maioria dos casos, você pode simplesmente alternar a chamada para pausestoryboard ou stopstoryboard, dependendo do caso específico. A única exceção é quando você precisa liberar recursos mantidos pelo storyboard ou usá -los para outro objetivo.

Se você realmente deseja remover o storyboard e manter os valores da propriedade, você deve definir os valores animados diretamente nas propriedades. Isso pode ser feito definindo cada valor para o valor animado, algo assim:

void CopyAnimatedValuesToLocalValues(DependencyObject obj)
{
  // Recurse down tree
  for(int i=0; i<VisualTreeHelper.GetChildrenCount(obj); i++)
    CopyAnimatedValuesToLocalValues(VisualTreeHelper.GetChild(obj, i));

  var enumerator = obj.GetLocalValueEnumerator();
  while(enumerator.MoveNext())
  {
    var prop = enumerator.Current.Property;
    var value = enumerator.Current.Value as Freezable;

    // Recurse into eg. brushes that may be set by storyboard, as long as they aren't frozen
    if(value!=null && !value.IsFrozen)
      CopyAnimatedValuesToLocalValues(value);

    // *** This is the key bit of code ***
    if(DependencyPropertyHelper.GetValueSource(obj, prop).IsAnimated)
      obj.SetValue(prop, obj.GetValue(prop));

  }
}

Ligue para isso imediatamente antes de remover o storyboard para copiar os valores animados.

Editar Foi feito um comentário de que esse código pode ser desnecessário, porque chamar a iniciação com BeginTime = NULL alcança um efeito semelhante.

Embora seja verdade que o início do BeginTime = NULL faz parecer que os valores foram copiados para o local, uma chamada posterior ao removestoryboard fará com que os valores sejam revertidos. Isso ocorre porque o início da modificação com BeginTime = NULL faz com que a animação anterior mantenha seus valores pendentes no início da nova animação, mas não faz nada para afetar os valores locais.

O código acima realmente substitui os valores locais, para que todas as animações possam ser removidas e os objetos ainda terão seus novos valores. Portanto, se você realmente deseja ligar para o Removestoryboard e ainda manter seus valores, precisará do código que escrevi acima ou algo parecido.

Outras dicas

Eu tive um problema semelhante ao usar AnimationTimeline. A solução mais fácil acabou sendo capturando o Completed evento em código atrás e antes de ligar BeginAnimation com o null Parâmetro Para remover a animação, obtenha o valor atual da propriedade e use -o para defini -lo.

Isso obtém o último valor animado e o define.

void OnCompleted( object sender, EventArgs args )
{
    // Required to copy latest animated value to local value.
    o.SomeValue = o.SomeValue;
    o.BeginAnimation( SomeClass.SomeValueProperty, null );
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top