Usando vinculação de dados para animações de lançamento em WPF
-
08-07-2019 - |
Pergunta
Eu estou tentando adaptar um aplicativo WPF simples de usar o padrão Model-View-ViewModel. Na minha página eu tenho um par de animações:
<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>
Atualmente eu começar a animação no de trás do código, e pode ouvir o evento Concluída a fazer algo quando ele termina com o seguinte código:
storyboardRight = (Storyboard)TryFindResource("storyboardRight");
storyboardRight.Completed += new EventHandler(storyboardRight_Completed);
storyboardRight.Begin(this);
Existe uma maneira de ligação de dados do storyboard para meu ViewModel para que ele começa em um evento gerado pelo ViewModel e pode chamar-back em que ViewModel quando ele for concluído?
Solução
Eu tive a oportunidade de colocar esta pergunta a Josh torção da Microsoft, que gentilmente tomou o tempo para dar uma resposta a este problema. A solução é usar um DataTrigger
em combinação com um enum no ViewModel para lançar o Storyboard, e este por sua vez, requer colocar a página em um ContentPresenter
. Para lidar com a conclusão de animação, uma pequena quantidade de trás código foi obrigado a fazer uma chamada para um ICommand
no ViewModel.
O Leia Josh pós aqui para uma descrição completa da solução.
Outras dicas
Eu fiz isso por um usando DataTrigger e vinculando-o a uma propriedade em meu ViewModel. Quando a propriedade "FlashingBackGround" é configurado para "ON" a animação começa Storyboard.
Certifique-se também incluir em seu projeto uma referência a "Microsoft.Expression.Interactions"
XAML: (este vai diretamente no nó de raiz)
<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, o ViewModel deve herdar "INotifyPropertyChanged"
Você precisa usar uma EventTrigger
. Este href="http://www.microsoft.com/emea/msdn/thepanel/en/articles/animations_wpf.aspx" noreferrer"> artigo eventos roteados Visão geral no MSDN e Como:. usar triggers eventos para controlar um Storyboard após seu início