wpf data-binding animation mvvm

Usar enlace de datos para lanzar animaciones en WPF



data-binding animation (3)

Estoy tratando de adaptar una aplicación WPF simple para usar el patrón Model-View-ViewModel. En mi página tengo un par de animaciones:

<Page.Resources> <Storyboard x:Name="storyboardRight" x:Key="storyboardRight"> <DoubleAnimation x:Name="da3" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" /> <DoubleAnimation x:Name="da4" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:1" Duration="0:0:0.5" /> </Storyboard> ... </Page.Resources>

Actualmente comienzo la animación en el código subyacente, y puedo escuchar el evento Completado para hacer algo cuando termina con el siguiente código:

storyboardRight = (Storyboard)TryFindResource("storyboardRight"); storyboardRight.Completed += new EventHandler(storyboardRight_Completed); storyboardRight.Begin(this);

¿Hay alguna manera de vincular datos a mi ViewModel con el storyboard para que comience en un evento generado por ViewModel y pueda devolver la llamada en ese ViewModel cuando haya terminado?



Tuve la oportunidad de formularle esta pregunta a Josh Twist de Microsoft, quien amablemente se tomó el tiempo de dar una respuesta a este problema. La solución es usar un DataTrigger en combinación con una enumeración en el ViewModel para iniciar Storyboard, y esto a su vez requiere colocar la página en un ContentPresenter . Para manejar la finalización de la animación, se requirió una pequeña cantidad de código para realizar una llamada a ICommand en ViewModel.

Lea la publicación de Josh aquí para obtener una descripción completa de la solución.


Lo hice usando un DataTrigger y vinculándolo a una propiedad en mi ViewModel. Cuando la propiedad "FlashingBackGround" se configura en "ON", se inicia la animación Storyboard.

También asegúrese de incluir en su proyecto una referencia a "Microsoft.Expression.Interactions"

XAML: (esto va directamente en el nodo raíz)

<Window xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Name="window" > ... <i:Interaction.Triggers> <ei:DataTrigger Binding="{Binding FlashingBackground, Mode=OneWay}" Value="ON"> <ei:ControlStoryboardAction Storyboard="{StaticResource MyAnimation}" ControlStoryboardOption="Play"/> </ei:DataTrigger> </i:Interaction.Triggers> ... </Window>

ViewModel:

private void TurnOnFlashingBackround() { this.FlashingBackground = "ON"; } private string _FlashingBackround = "OFF"; public string FlashingBackground { get { return this._FlashingBackround; } private set { if (this.FlashingBackground == value) { return; } this._FlashingBackround = value; this.OnPropertyChanged("FlashingBackground"); } } public new event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged( this, new PropertyChangedEventArgs(propertyName)); } }

Finalmente, el Viewmodel debe heredar de "INotifyPropertyChanged"