通过ControlStoryboardAction从ViewModel启动Storyboard不起作用

时间:2015-12-12 18:52:39

标签: c# wpf mvvm event-triggers

我正在尝试从我的viewmodel开始一个故事板动画。我的想法是,每当我的应用程序稍后从服务器接收位置更新时都会有一个动画,但是现在可以通过按下更新位置和启动动画的概念验证。一个按钮

我的第一种方法是使用Microsoft.Expression.Interactivity ControlStoryboardAction(请随意告诉我是否有更好的方法来实现我想要的目标)。我将触发器绑定到CanAnimate属性,默认情况下设置为true,因此动画应该在加载后立即开始 - 但事实并非如此。 当我使用Eventtrigger时,故事板会起作用,但这不是我想要的:

<Window x:Class="AnimationExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AnimationExample"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

    <Canvas Name="CanvasWrapper" Width="525" Height="350">
        <Ellipse Fill="Red" Width="60" Height="60" Canvas.Left="60" Canvas.Top="60">
            <Ellipse.Resources>
                <Storyboard x:Key="Movement">
                    <DoubleAnimation
                                Storyboard.TargetProperty="(Canvas.Left)"
                                Duration="0:0:0.1" To="{Binding NextPosX}" />
                    <DoubleAnimation
                                Storyboard.TargetProperty="(Canvas.Top)"
                                Duration="0:0:0.1" To="{Binding NextPosY}" />
                </Storyboard>
            </Ellipse.Resources>
            <!-- This trigger is just for testing and works fine! -->
            <Ellipse.Triggers>
                <EventTrigger RoutedEvent="Ellipse.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard  Storyboard="{StaticResource Movement}"/>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Ellipse.Triggers>
            <!-- This trigger doesn't works -->
            <i:Interaction.Triggers>
                <ei:DataTrigger Binding="{Binding CanAnimate}" Value="True" Comparison="Equal">
                    <ei:ControlStoryboardAction Storyboard="{StaticResource Movement}" ControlStoryboardOption="Play" />
                </ei:DataTrigger>
            </i:Interaction.Triggers>
        </Ellipse>
    </Canvas>
</Window>

到目前为止,这是我的viewmodel。显然缺少对ActionCommand的绑定,ActionCommand也应该更改CanAnimate,以便再次触发动画,但由于CanAnimate为真,它仍然应该动画一次:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace AnimationExample
{
    class MainWindowViewModel : INotifyPropertyChanged
    {

        int _nextPosX = 120;

        public int NextPosX
        {
            get { return _nextPosX; }
            set
            {
                if (value != _nextPosX)
                {
                    _nextPosX = value;
                    OnPropertyChanged("NextPosX");
                }
            }
        }

        int _nextPosY = 120;

        public int NextPosY
        {
            get { return _nextPosY; }
            set
            {
                if (value != _nextPosY)
                {
                    _nextPosY = value;
                    OnPropertyChanged("NextPosY");
                }
            }
        }

        bool _canAnimate = true;

        public bool CanAnimate
        {
            get { return _canAnimate; }
            set
            {
                if (value != _canAnimate)
                {
                    _canAnimate = value;
                    OnPropertyChanged("CanAnimate");
                }
            }
        }

        ICommand _calculate;
        public ICommand CalculateNextPos
        {
            get
            {
                if(_calculate == null)
                {
                    _calculate = new ActionCommand(dummy =>
                    {
                        NextPosX = 500;
                        NextPosY = 500;
                    }, dummy => true);
                }
                return _calculate;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

}

提前致谢!

0 个答案:

没有答案