Animações com storyboard

As animações com storyboard não são apenas animações no sentido visual. Uma animação com storyboard é uma maneira de alterar o valor de uma propriedade de dependência em função do tempo. Um dos principais motivos pelos quais você pode precisar de uma animação com storyboard que não seja da biblioteca de animação é definir o estado visual de um controle, como parte de um modelo de controle ou definição de página.

Diferenças com o Silverlight e o WPF

Se você estiver familiarizado com o Microsoft Silverlight ou o Windows Presentation Foundation (WPF), leia esta seção; caso contrário, você pode ignorá-lo.

Em geral, a criação de animações com storyboard em um aplicativo do Tempo de Execução do Windows é como o Silverlight ou o WPF. Mas há uma série de diferenças importantes:

  • As animações com storyboard não são a única maneira de animar visualmente uma interface do usuário, nem são necessariamente a maneira mais fácil para os desenvolvedores de aplicativos fazerem isso. Em vez de usar animações com storyboard, geralmente é uma prática de design melhor usar animações de tema e animações de transição. Eles podem criar rapidamente animações de interface do usuário recomendadas sem entrar nas complexidades do direcionamento de propriedades de animação. Para obter mais informações, consulte Visão geral das animações.
  • No Tempo de Execução do Windows, muitos controles XAML incluem animações de tema e animações de transição como parte de seu comportamento interno. Na maioria das vezes, os controles WPF e Silverlight não tinham um comportamento de animação padrão.
  • Nem todas as animações personalizadas que você cria podem ser executadas por padrão em um aplicativo do Tempo de Execução do Windows, se o sistema de animação determinar que a animação pode causar um desempenho ruim em sua interface do usuário. As animações em que o sistema determina que pode haver um impacto no desempenho são chamadas de animações dependentes. É dependente porque o relógio da animação está trabalhando diretamente no thread da interface do usuário, que também é onde a entrada do usuário ativo e outras atualizações estão tentando aplicar as alterações de tempo de execução à interface do usuário. Uma animação dependente que está consumindo recursos extensivos do sistema no thread da interface do usuário pode fazer com que o aplicativo pareça não responder em determinadas situações. Se a animação causar uma alteração de layout ou tiver o potencial de afetar o desempenho no thread da interface do usuário, geralmente será necessário habilitar explicitamente a animação para vê-la ser executada. É para isso que serve a propriedade EnableDependentAnimation em classes de animação específicas. Consulte Animações dependentes e independentes para obter mais informações.
  • No momento, não há suporte para funções de easing personalizadas no Tempo de Execução do Windows.

Definindo animações com storyboard

Uma animação com storyboard é uma maneira de alterar o valor de uma propriedade de dependência em função do tempo. A propriedade que você está animando nem sempre é uma propriedade que afeta diretamente a interface do usuário do seu aplicativo. Mas como o XAML trata da definição da interface do usuário para um aplicativo, geralmente é uma propriedade relacionada à interface do usuário que você está animando. Por exemplo, você pode animar o ângulo de um RotateTransform ou o valor de cor do plano de fundo de um botão.

Um dos principais motivos pelos quais você pode estar definindo uma animação com storyboard é se você for um autor de controle ou estiver modelando novamente um controle e estiver definindo estados visuais. Para obter mais informações, consulte Animações com storyboard para estados visuais.

Se você estiver definindo estados visuais ou uma animação personalizada para um aplicativo, os conceitos e APIs para animações com storyboard descritos neste tópico se aplicam principalmente a ambos.

Para ser animada, a propriedade que você está direcionando com uma animação de storyboard deve ser uma propriedade de dependência. Uma propriedade de dependência é um recurso importante da implementação XAML do Tempo de Execução do Windows. As propriedades graváveis da maioria dos elementos comuns da interface do usuário normalmente são implementadas como propriedades de dependência, para que você possa animá-las, aplicar valores associados a dados ou aplicar um Style e direcionar a propriedade com um Setter. Para obter mais informações sobre como as propriedades de dependência funcionam, consulte Visão geral das propriedades de dependência.

Na maioria das vezes, você define uma animação com storyboard escrevendo XAML. Se você usar uma ferramenta como o Microsoft Visual Studio, ela produzirá o XAML para você. Também é possível definir uma animação com storyboard usando código, mas isso é menos comum.

Vejamos um exemplo simples. Neste exemplo XAML, a propriedade Opacity é animada em um objeto Rectangle específico.

<Page ...>
  <Page.Resources>
    <!-- Storyboard resource: Animates a rectangle's opacity. -->
    <Storyboard x:Name="myStoryboard">
      <DoubleAnimation
        Storyboard.TargetName="MyAnimatedRectangle"
        Storyboard.TargetProperty="Opacity"
        From="1.0" To="0.0" Duration="0:0:1"/>
    </Storyboard>
  </Page.Resources>

  <!--Page root element, UI definition-->
  <Grid>
    <Rectangle x:Name="MyAnimatedRectangle"
      Width="300" Height="200" Fill="Blue"/>
  </Grid>
</Page>

Identificando o objeto a ser animado

No exemplo anterior, o storyboard estava animando a propriedade Opacity de um Rectangle. Você não declara as animações no objeto em si. Em vez disso, você faz isso dentro da definição de animação de um storyboard. Os storyboards geralmente são definidos em XAML que não está nas imediações da definição da interface do usuário XAML do objeto a ser animado. Em vez disso, eles geralmente são configurados como um recurso XAML.

Para conectar uma animação a um destino, faça referência ao destino por seu nome de programação de identificação. Você sempre deve aplicar o atributo x:Name na definição da interface do usuário XAML para nomear o objeto que deseja animar. Em seguida, você direciona o objeto a ser animado definindo Storyboard.TargetName na definição de animação. Para o valor de Storyboard.TargetName, você usa a cadeia de caracteres de nome do objeto de destino, que é o que você definiu anteriormente e em outro lugar com o atributo x:Name.

Direcionando a propriedade de dependência para animar

Você define um valor para Storyboard.TargetProperty na animação. Isso determina qual propriedade específica do objeto de destino é animada.

Às vezes, você precisa direcionar uma propriedade que não é uma propriedade imediata do objeto de destino, mas que está aninhada mais profundamente em uma relação objeto-propriedade. Muitas vezes, você precisa fazer isso para fazer uma busca detalhada em um conjunto de valores de objetos e propriedades contribuintes até que possa fazer referência a um tipo de propriedade que possa ser animado (Double, Point, Color). Esse conceito é chamado de direcionamento indireto, e a sintaxe para direcionar uma propriedade dessa maneira é conhecida como um caminho de propriedade.

Veja um exemplo. Um cenário comum para uma animação com storyboard é alterar a cor de uma parte da interface do usuário ou controle de um aplicativo para representar que o controle está em um estado específico. Digamos que você queira animar o Foreground de um TextBlock, para que ele mude de vermelho para verde. Você esperaria que um ColorAnimation estivesse envolvido, e isso está correto. No entanto, nenhuma das propriedades nos elementos da interface do usuário que afetam a cor do objeto é realmente do tipo Color. Em vez disso, eles são do tipo Brush. Portanto, o que você realmente precisa direcionar para animação é a propriedade Color da classe SolidColorBrush, que é um tipo derivado de Brush que normalmente é usado para essas propriedades de interface do usuário relacionadas a cores. E aqui está o que isso parece em termos de formação de um caminho de propriedade para o direcionamento de propriedades da sua animação:

<Storyboard x:Name="myStoryboard">
  <ColorAnimation
    Storyboard.TargetName="tb1"
    Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
    From="Red" To="Green"/>
</Storyboard>

Veja como pensar nessa sintaxe em termos de suas partes:

  • Cada conjunto de parênteses () inclui um nome de propriedade.
  • Dentro do nome da propriedade, há um ponto, e esse ponto separa um nome de tipo e um nome de propriedade, para que a propriedade que você está identificando seja inequívoca.
  • O ponto no meio, aquele que não está entre parênteses, é um degrau. Isso é interpretado pela sintaxe como significando, pegue o valor da primeira propriedade (que é um objeto), entre em seu modelo de objeto e direcione uma subpropriedade específica do valor da primeira propriedade.

Aqui está uma lista de cenários de direcionamento de animação em que você provavelmente usará o direcionamento de propriedade indireto e algumas cadeias de caracteres de caminho de propriedade que se aproximam da sintaxe que você usará:

Você notará que alguns desses exemplos usam colchetes em torno de números. Este é um indexador. Ele indica que o nome da propriedade que o precede tem uma coleção como valor e que você deseja um item (conforme identificado por um índice baseado em zero) de dentro dessa coleção.

Você também pode animar propriedades anexadas XAML. Sempre coloque o nome completo da propriedade anexada entre parênteses, por exemplo (Canvas.Left). Para obter mais informações, consulte Animando propriedades anexadas XAML.

Para obter mais informações sobre como usar um caminho de propriedade para direcionamento indireto da propriedade a ser animada, consulte Sintaxe de caminho de propriedade ou Propriedade anexada Storyboard.TargetProperty.

Tipos de animação

O sistema de animação do Tempo de Execução do Windows tem três tipos específicos aos quais as animações com storyboard podem ser aplicadas:

Há também um tipo de animação de objeto generalizado para valores de referência de objeto, que discutiremos mais adiante.

Especificando os valores animados

Até agora, mostramos como direcionar o objeto e a propriedade para animar, mas ainda não descrevemos o que a animação faz com o valor da propriedade quando é executada.

Os tipos de animação que descrevemos às vezes são chamados de animações From/To/By. Isso significa que a animação está alterando o valor de uma propriedade, ao longo do tempo, usando uma ou mais dessas entradas provenientes da definição de animação:

  • O valor começa no valor De . Se você não especificar um valor De , o valor inicial será qualquer valor que a propriedade animada tenha no momento antes da execução da animação. Pode ser um valor padrão, um valor de um estilo ou modelo ou um valor aplicado especificamente por uma definição de interface do usuário XAML ou código de aplicativo.
  • No final da animação, o valor é o valor Para .
  • Ou, para especificar um valor final relativo ao valor inicial, defina a propriedade By . Você definiria isso em vez da propriedade To .
  • Se você não especificar um valor Para ou um valor By , o valor final será qualquer valor que a propriedade animada tenha no momento anterior à execução da animação. Nesse caso, é melhor ter um valor From porque, caso contrário, a animação não alterará o valor; seus valores inicial e final são os mesmos.
  • Uma animação normalmente tem pelo menos um de De, Por ou Para, mas nunca todos os três.

Vamos revisitar o exemplo XAML anterior e examinar novamente os valores From e To e a Duration. O exemplo está animando a propriedade Opacity e o tipo de propriedade de Opacity é Double. Portanto, a animação a ser usada aqui é DoubleAnimation.

From="1.0" To="0.0" especifica que, quando a animação é executada, a propriedade Opacity começa com um valor de 1 e é animada como 0. Em outras palavras, em termos do que esses valores Double significam para a propriedade Opacity , essa animação fará com que o objeto comece opaco e, em seguida, desapareça para transparente.

...
<Storyboard x:Name="myStoryboard">
  <DoubleAnimation
    Storyboard.TargetName="MyAnimatedRectangle"
    Storyboard.TargetProperty="Opacity"
    From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>
...

Duration="0:0:1" Especifica quanto tempo dura a animação, ou seja, a rapidez com que o retângulo desaparece. Uma propriedade Duration é especificada na forma de horas:minutos:segundos. A duração de tempo neste exemplo é de um segundo.

Para obter mais informações sobre valores de Duração e a sintaxe XAML, consulte Duração.

Observação

Para o exemplo que mostramos, se você tivesse certeza de que o estado inicial do objeto que está sendo animado tem Opacity sempre igual a 1, seja por meio do padrão ou de um conjunto explícito, você poderia omitir o valor From , a animação usaria o valor inicial implícito e o resultado seria o mesmo.

De/Para/Por são anuláveis

Mencionamos anteriormente que você pode omitir De, Para ou Por e, portanto, usar valores atuais não animados como substitutos para um valor ausente. As propriedades De, Para ou Por de uma animação não são do tipo que você pode imaginar. Por exemplo, o tipo da propriedade DoubleAnimation.To não é Double. Em vez disso, é um anulável para Double. E seu valor padrão é nulo, não 0. Esse valor nulo é como o sistema de animação distingue que você não definiu especificamente um valor para uma propriedade From, To ou By . As extensões de componente do Visual C++ (C++/CX) não têm um tipo Nullable , portanto, ele usa IReference .

Outras propriedades de uma animação

As próximas propriedades descritas nesta seção são todas opcionais, pois têm padrões apropriados para a maioria das animações.

AutoReverse

Se você não especificar AutoReverse ou RepeatBehavior em uma animação, essa animação será executada uma vez e executada pelo tempo especificado como Duration.

A propriedade AutoReverse especifica se uma linha do tempo é reproduzida ao contrário depois de atingir o final de sua Duração. Se você defini-lo como true, a animação será revertida depois de atingir o final de sua Duração declarada, alterando o valor de seu valor final (Para) de volta para seu valor inicial (De). Isso significa que a animação é executada efetivamente pelo dobro do tempo de sua duração.

Comportamento de repetição

A propriedade RepeatBehavior especifica quantas vezes uma linha do tempo é reproduzida ou uma duração maior na qual a linha do tempo deve se repetir. Por padrão, uma linha do tempo tem uma contagem de iteração de "1x", o que significa que ela é reproduzida uma vez por sua duração e não se repete.

Você pode fazer com que a animação execute várias iterações. Por exemplo, um valor de "3x" faz com que a animação seja executada três vezes. Ou você pode especificar uma duração diferente para RepeatBehavior. Essa duração deve ser maior que a duração da própria animação para ser efetiva. Por exemplo, se você especificar um RepeatBehavior de "0:0:10", para uma animação que tenha uma Duração de "0:0:2", essa animação será repetida cinco vezes. Se eles não se dividirem uniformemente, a animação será truncada no momento em que o tempo RepeatBehavior for atingido, o que pode estar no meio do caminho. Por fim, você pode especificar o valor especial "Para sempre", o que faz com que a animação seja executada infinitamente até que seja interrompida deliberadamente.

Para obter mais informações sobre os valores RepeatBehavior e a sintaxe XAML, consulte RepeatBehavior.

FillBehavior="Parar"

Por padrão, quando uma animação termina, a animação deixa o valor da propriedade como o valor final de Para ou Por modificado, mesmo depois que sua duração é ultrapassada. No entanto, se você definir o valor da propriedade FillBehavior como FillBehavior.Stop, o valor do valor animado será revertido para qualquer valor que fosse antes da animação ser aplicada ou, mais precisamente, para o valor efetivo atual, conforme determinado pelo sistema de propriedades de dependência (para obter mais informações sobre essa distinção, consulte Visão geral das propriedades de dependência).

Hora de Início

Por padrão, o BeginTime de uma animação é "0:0:0", portanto, ela começa assim que o Storyboard que o contém é executado. Você pode alterar isso se o Storyboard contiver mais de uma animação e você quiser escalonar os horários de início das outras em relação a uma animação inicial ou criar um pequeno atraso deliberado.

Relação de velocidade

Se você tiver mais de uma animação em um Storyboard , poderá alterar a taxa de tempo de uma ou mais animações em relação ao Storyboard. É o Storyboard pai que, em última análise, controla como o tempo de duração decorre enquanto as animações são executadas. Essa propriedade não é usada com muita frequência. Para obter mais informações, consulte SpeedRatio.

Definindo mais de uma animação em um Storyboard

O conteúdo de um Storyboard pode ser mais de uma definição de animação. Você pode ter mais de uma animação se estiver aplicando animações relacionadas a duas propriedades do mesmo objeto de destino. Por exemplo, você pode alterar as propriedades TranslateX e TranslateY de um TranslateTransform usado como o RenderTransform de um elemento de interface do usuário; isso fará com que o elemento seja convertido diagonalmente. Você precisa de duas animações diferentes para fazer isso, mas talvez queira que as animações façam parte do mesmo Storyboard porque você sempre deseja que essas duas animações sejam executadas juntas.

As animações não precisam ser do mesmo tipo ou direcionar o mesmo objeto. Eles podem ter durações diferentes e não precisam compartilhar nenhum valor de propriedade.

Quando o Storyboard pai for executado, cada uma das animações também será executada.

A classe Storyboard realmente tem muitas das mesmas propriedades de animação que os tipos de animação, porque ambas compartilham a classe base Timeline. Assim, um Storyboard pode ter um RepeatBehavior ou um BeginTime. Você geralmente não os define em um Storyboard , a menos que queira que todas as animações contidas tenham esse comportamento. Como regra geral, qualquer propriedade Timeline definida em um Storyboard se aplica a todas as suas animações filho. Se não for definido, o Storyboard terá uma duração implícita calculada a partir do valor de Duration mais longo das animações contidas. Um Duration definido explicitamente em um Storyboard que é menor do que uma de suas animações filho fará com que essa animação seja cortada, o que geralmente não é desejável.

Um storyboard não pode conter duas animações que tentam direcionar e animar a mesma propriedade no mesmo objeto. Se você tentar isso, receberá um erro de tempo de execução quando o storyboard tentar ser executado. Essa restrição se aplica mesmo que as animações não se sobreponham no tempo devido a valores e durações BeginTime deliberadamente diferentes. Se você realmente deseja aplicar uma linha do tempo de animação mais complexa à mesma propriedade em um único storyboard, a maneira de fazer isso é usar uma animação de quadro-chave. Consulte Animações de quadro-chave e função de atenuação.

O sistema de animação pode aplicar mais de uma animação ao valor de uma propriedade, se essas entradas vierem de vários storyboards. Usar esse comportamento deliberadamente para executar storyboards simultaneamente não é comum. No entanto, é possível que uma animação definida pelo aplicativo que você aplica a uma propriedade de controle esteja modificando o valor HoldEnd de uma animação que foi executada anteriormente como parte do modelo de estado visual do controle.

Definindo um storyboard como um recurso

Um Storyboard é o contêiner no qual você coloca objetos de animação. Normalmente, você define o Storyboard como um recurso disponível para o objeto que deseja animar, seja em Resources no nível da página ou em Application.Resources.

Este próximo exemplo mostra como o Storyboard do exemplo anterior estaria contido em uma definição de Resources no nível da página, em que o Storyboard é um recurso com chave da Page raiz. Observe o atributo x:Name. Esse atributo é como você define um nome de variável para o Storyboard, para que outros elementos em XAML, bem como o código, possam se referir ao Storyboard posteriormente.

<Page ...>
  <Page.Resources>
    <!-- Storyboard resource: Animates a rectangle's opacity. -->
    <Storyboard x:Name="myStoryboard">
      <DoubleAnimation
        Storyboard.TargetName="MyAnimatedRectangle"
        Storyboard.TargetProperty="Opacity"
        From="1.0" To="0.0" Duration="0:0:1"/>
    </Storyboard>
  </Page.Resources>
  <!--Page root element, UI definition-->
  <Grid>
    <Rectangle x:Name="MyAnimatedRectangle"
      Width="300" Height="200" Fill="Blue"/>
  </Grid>
</Page>

Definir recursos na raiz XAML de um arquivo XAML, como page.xaml ou app.xaml, é uma prática comum de como organizar recursos com chave em seu XAML. Você também pode fatorar recursos em arquivos separados e mesclá-los em aplicativos ou páginas. Para obter mais informações, consulte ResourceDictionary e referências de recursos XAML.

Observação

O XAML do Tempo de Execução do Windows dá suporte à identificação de recursos usando o atributo x:Key ou o atributo x:Name. O uso do atributo x:Name é mais comum para um Storyboard, pois você desejará referenciá-lo pelo nome da variável eventualmente, para que possa chamar seu método Begin e executar as animações. Se você usar o atributo x:Key, precisará usar métodos ResourceDictionary, como o indexador Item, para recuperá-lo como um recurso com chave e, em seguida, converter o objeto recuperado no Storyboard para usar os métodos Storyboard.

Storyboards para estados visuais

Você também coloca suas animações em uma unidade Storyboard quando está declarando as animações de estado visual para a aparência visual de um controle. Nesse caso, os elementos Storyboard definidos vão para um contêiner VisualState aninhado mais profundamente em um Style (é o Style que é o recurso com chave). Você não precisa de uma chave ou nome para o Storyboard nesse caso, pois é o VisualState que tem um nome de destino que o VisualStateManager pode invocar. Os estilos dos controles geralmente são fatorados em arquivos XAML ResourceDictionary separados, em vez de colocados em uma página ou coleção de recursos do aplicativo. Para obter mais informações, consulte Animações com storyboard para estados visuais.

Animações dependentes e independentes

Neste ponto, precisamos introduzir alguns pontos importantes sobre como funciona o sistema de animação. Em particular, a animação interage fundamentalmente com a forma como um aplicativo do Tempo de Execução do Windows é renderizado na tela e como essa renderização usa threads de processamento. Um aplicativo do Tempo de Execução do Windows sempre tem um thread de interface do usuário principal, e esse thread é responsável por atualizar a tela com as informações atuais. Além disso, um aplicativo do Tempo de Execução do Windows tem um thread de composição, que é usado para pré-calcular layouts imediatamente antes de serem mostrados. Quando você anima a interface do usuário, há potencial para causar muito trabalho para o thread da interface do usuário. O sistema deve redesenhar grandes áreas da tela usando intervalos de tempo bastante curtos entre cada atualização. Isso é necessário para capturar o valor de propriedade mais recente da propriedade animada. Se você não for cuidadoso, há o risco de que uma animação possa tornar a interface do usuário menos responsiva ou afetar o desempenho de outros recursos do aplicativo que também estão no mesmo thread da interface do usuário.

A variedade de animação que é determinada como tendo algum risco de desacelerar o thread da interface do usuário é chamada de animação dependente. Uma animação não sujeita a esse risco é uma animação independente. A distinção entre animações dependentes e independentes não é determinada apenas por tipos de animação (DoubleAnimation e assim por diante), como descrevemos anteriormente. Em vez disso, ele é determinado por quais propriedades específicas você está animando e outros fatores, como herança e composição de controles. Há circunstâncias em que, mesmo que uma animação altere a interface do usuário, a animação pode ter um impacto mínimo no thread da interface do usuário e, em vez disso, pode ser tratada pelo thread de composição como uma animação independente.

Uma animação é independente se tiver qualquer uma destas características:

Aviso

Para que sua animação seja tratada como independente, você deve definir Duration="0"explicitamente . Por exemplo, se você remover Duration="0" desse XAML, a animação será tratada como dependente, mesmo que o KeyTime do quadro seja "0:0:0".

<Storyboard>
  <DoubleAnimationUsingKeyFrames
    Duration="0"
    Storyboard.TargetName="Button2"
    Storyboard.TargetProperty="Width">
    <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="200"/>
  </DoubleAnimationUsingKeyFrames>
</Storyboard>

Se sua animação não atender a esses critérios, provavelmente é uma animação dependente. Por padrão, o sistema de animação não executará uma animação dependente. Portanto, durante o processo de desenvolvimento e teste, talvez você nem esteja vendo sua animação em execução. Você ainda pode usar essa animação, mas deve habilitar especificamente cada uma dessas animações dependentes. Para habilitar sua animação, defina a propriedade EnableDependentAnimation do objeto de animação como true. (Cada A subclasse Timeline que representa uma animação tem uma implementação diferente da propriedade, mas todas são nomeadas EnableDependentAnimation.)

O requisito de habilitar animações dependentes que recaem sobre o desenvolvedor do aplicativo é um aspecto de design consciente do sistema de animação e da experiência de desenvolvimento. Queremos que os desenvolvedores estejam cientes de que as animações têm um custo de desempenho para a capacidade de resposta da interface do usuário. Animações com baixo desempenho são difíceis de isolar e depurar em um aplicativo em grande escala. Portanto, é melhor ativar apenas as animações dependentes que você realmente precisa para a experiência de interface do usuário do seu aplicativo. Não queríamos tornar muito fácil comprometer o desempenho do seu aplicativo por causa de animações decorativas que usam muitos ciclos. Para obter mais informações sobre dicas de desempenho para animação, consulte Otimizar animações e mídia.

Como desenvolvedor de aplicativos, você também pode optar por aplicar uma configuração em todo o aplicativo que sempre desabilita animações dependentes, mesmo aquelas em que EnableDependentAnimation é true. Consulte Timeline.AllowDependentAnimations.

Dica

Se você estiver usando o Painel de Animação no Blend for Visual Studio 2019, sempre que tentar aplicar uma animação dependente a uma propriedade de estado visual, os avisos serão exibidos no designer. Os avisos não serão exibidos na saída de build ou na Lista de Erros. Se você estiver editando XAML manualmente, o designer não mostrará um aviso. Em tempo de execução durante a depuração, a saída de depuração do painel Saída mostrará um aviso de que a animação não é independente e será ignorada.

Iniciando e controlando uma animação

Tudo o que mostramos até agora não faz com que uma animação seja executada ou aplicada! Até que a animação seja iniciada e esteja em execução, as alterações de valor que uma animação está declarando em XAML estão latentes e ainda não acontecerão. Você deve iniciar explicitamente uma animação de alguma forma relacionada ao tempo de vida do aplicativo ou à experiência do usuário. No nível mais simples, você inicia uma animação chamando o método Begin no Storyboard que é o pai dessa animação. Você não pode chamar métodos do XAML diretamente, portanto, o que quer que você faça para habilitar suas animações, você o fará a partir do código. Esse será o code-behind para as páginas ou componentes do seu aplicativo, ou talvez a lógica do seu controle se você estiver definindo uma classe de controle personalizada.

Normalmente, você chamará Begin e apenas deixará a animação ser executada até a conclusão da duração. No entanto, você também pode usar os métodos Pause, Resume e Stop para controlar o Storyboard em tempo de execução, bem como outras APIs usadas para cenários de controle de animação mais avançados.

Quando você chama Begin em um storyboard que contém uma animação que se repete infinitamente (RepeatBehavior="Forever"), essa animação é executada até que a página que a contém seja descarregada ou você chame especificamente Pause ou Stop.

Iniciar uma animação a partir do código do aplicativo

Você pode iniciar animações automaticamente ou em resposta a ações do usuário. Para o caso automático, você normalmente usa um evento de tempo de vida do objeto, como Loaded , para atuar como o gatilho de animação. O evento Loaded é um bom evento para usar para isso porque, nesse ponto, a interface do usuário está pronta para interação e a animação não será cortada no início porque outra parte da interface do usuário ainda estava carregando.

Neste exemplo, o evento PointerPressed é anexado ao retângulo para que, quando o usuário clicar no retângulo, a animação comece.

<Rectangle PointerPressed="Rectangle_Tapped"
  x:Name="MyAnimatedRectangle"
  Width="300" Height="200" Fill="Blue"/>

O manipulador de eventos inicia o Storyboard (a animação) usando o método Begin do Storyboard.

myStoryboard.Begin();
myStoryboard().Begin();
myStoryboard->Begin();
myStoryBoard.Begin()

Você pode manipular o evento Completed se quiser que outra lógica seja executada depois que a animação terminar de aplicar valores. Além disso, para solucionar problemas de interações de sistema/animação de propriedades, o método GetAnimationBaseValue pode ser útil.

Dica

Sempre que você estiver codificando para um cenário de aplicativo em que está iniciando uma animação a partir do código do aplicativo, talvez queira examinar novamente se uma animação ou transição já existe na biblioteca de animação para seu cenário de interface do usuário. As animações da biblioteca permitem uma experiência de interface do usuário mais consistente em todos os aplicativos do Tempo de Execução do Windows e são mais fáceis de usar.

 

Animações para estados visuais

O comportamento de execução de um Storyboard usado para definir o estado visual de um controle é diferente de como um aplicativo pode executar um storyboard diretamente. Conforme aplicado a uma definição de estado visual em XAML, o Storyboard é um elemento de um VisualState que o contém, e o estado como um todo é controlado usando a API VisualStateManager. Todas as animações dentro serão executadas de acordo com seus valores de animação e propriedades Timeline quando o VisualState que o contém for usado por um controle. Para obter mais informações, consulte Storyboards para estados visuais. Para estados visuais, o FillBehavior aparente é diferente. Se um estado visual for alterado para outro estado, todas as alterações de propriedade aplicadas pelo estado visual anterior e suas animações serão canceladas, mesmo que o novo estado visual não aplique especificamente uma nova animação a uma propriedade.

Storyboard e EventTrigger

Há uma maneira de iniciar uma animação que pode ser declarada inteiramente em XAML. No entanto, essa técnica não é mais amplamente utilizada. É uma sintaxe herdada do WPF e das versões anteriores do Silverlight anteriores ao suporte ao VisualStateManager. Essa sintaxe EventTrigger ainda funciona no XAML do Tempo de Execução do Windows por motivos de importação/compatibilidade, mas só funciona para um comportamento de gatilho baseado no evento FrameworkElement.Loaded; a tentativa de disparar outros eventos gerará exceções ou falhará na compilação. Para obter mais informações, consulte EventTrigger ou BeginStoryboard.

Animando propriedades anexadas XAML

Não é um cenário comum, mas você pode aplicar um valor animado a uma propriedade anexada XAML. Para obter mais informações sobre o que são propriedades anexadas e como elas funcionam, consulte Visão geral das propriedades anexadas. O direcionamento de uma propriedade anexada requer uma sintaxe de caminho de propriedade que coloque o nome da propriedade entre parênteses. Você pode animar as propriedades anexadas internas, como Canvas.ZIndex, usando um ObjectAnimationUsingKeyFrames que aplica valores inteiros discretos. No entanto, uma limitação existente da implementação XAML do Tempo de Execução do Windows é que você não pode animar uma propriedade anexada personalizada.

Mais tipos de animação e próximas etapas para aprender sobre como animar sua interface do usuário

Até agora, mostramos as animações personalizadas que estão animando entre dois valores e, em seguida, interpolando linearmente os valores conforme necessário enquanto a animação é executada. Eles são chamados de animações From/To/By. Mas há outro tipo de animação que permite declarar valores intermediários que ficam entre o início e o fim. Eles são chamados de animações de quadro-chave. Também há uma maneira de alterar a lógica de interpolação em uma animação From/To/By ou em uma animação de quadro-chave. Isso envolve a aplicação de uma função de atenuação. Para obter mais informações sobre esses conceitos, consulte Animações de quadro-chave e função de atenuação.