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?

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top