Animando transições em WPF e Silverlight–Parte I–Code Behind

Quando eu vi uma pergunta de um usuário nos forums do MSDN sobre animação de um user control para dar o efeito de saída ao clicar um botão, eu pensei que esta seria uma excelente oportunidade de criar uma série de posts aqui no blog, mostrando diversas maneiras de fazê-lo.

Apesar de colocar as alternativas aqui, algumas podem não ser tão boas: este post onde eu ponho animação no code behind, apesar de ser fácil de implementar, tem algumas desvantagens:

  • O código da animação é posto no code behind, uma técnica que eu não gosto. Eu nao acho que o padrão MVVM deva ter zero code behind, mas eu não gosto de por código lá, a menos que seja indispensável e estritamente relacionado com a view.
  • Não é design-friendly – se o designer quer mudar a animação, o código deve ser alterado.
  • Não é portável – se você quer criar a mesma animação em outros lugares, o código deve ser copiado ou refatorado para ser acessado de outros lugares.
  • Não é fácil de manipular – tudo é feito em código. Quaisquer mudanças, como a duração da animação deve ser alterado em código.

Temos o seguinte problema: temos um controle na janela e queremos escondê-lo quando o botão é clicado, usando uma animação, como vemos abaixo:

image_thumbimage_thumb1image_thumb3image_thumb4

Para fazer isso, devemos criar uma animação para o controle, do tipo RenderTransform e animá-la. Podemos fazer tudo em código desta maneira: no clique do botão, criamos a transformação, adicionamos ao controle e animamos ela:

 

private void Button_Click(object sender, RoutedEventArgs e) { // create the transformation and add it to the control var translate = new TranslateTransform(0, 0); gridLogin.RenderTransform = translate; // create the animation and start it var da = new DoubleAnimation(0, -ActualWidth, new Duration(TimeSpan.FromMilliseconds(1000))); translate.BeginAnimation(TranslateTransform.XProperty, da); }


Este código tem muitos inconvenientes:

  • Ele só pode ser aplicado ao nosso controle. Para adicioná-lo a outro controle, devemos copiar o código.
  • A duração da animação é 1 segundo – a duração é fixa.
  • Somente anima da direita para a esquerda.

Nesta primeira fase, refatoraremos o código para deixá-lo mais genérico:

public enum AnimationType { Right, Left, Up, Down } private void Button_Click(object sender, RoutedEventArgs e) { AnimateControl(gridLogin, TimeSpan.FromMilliseconds(1000), AnimationType.Left); } private void AnimateControl(UIElement control, TimeSpan duration, AnimationType type) { double xEnd = 0; double yEnd = 0; if (type == AnimationType.Left) xEnd = -ActualWidth; else if (tipo == AnimationType.Right) xEnd = ActualWidth; else if (tipo == AnimationType.Up) yEnd = -ActualHeight; else if (tipo == AnimationType.Down) yEnd = ActualHeight; // create the transformation and add it to the control var translate = new TranslateTransform(0, 0); control.RenderTransform = translate; // create the animation and start it if (tipo == AnimationType.Left || tipo == AnimationType.Right) { var da = new DoubleAnimation(0, xEnd, new Duration(duration)); translate.BeginAnimation(TranslateTransform.XProperty, da); } else { var da = new DoubleAnimation(0, yEnd, new Duration(duration)); translate.BeginAnimation(TranslateTransform.YProperty, da); } }




Apesar do código ser maior, ele é mais genérico e permite ser reutilizado. Podemos usar qualquer controle, configurar a deuração e a direção da animação. Ainda não é o idela, mas é melhor que o código anterior, não reutilizável. Nos próximos posts veremos outras maneiras de fazer isso. Até lá!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>