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?
Necesitas usar un EventTrigger
. Este artículo sobre Animaciones en WPF podría ayudar. Consulte también la Descripción general de eventos enrutados en MSDN y Cómo usar: Desencadenantes de eventos para controlar un guión gráfico después de que comience .
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"