1

我正在尝试从我的视图模型开始一个故事板动画。这个想法是,以后每次我的应用程序从服务器接收到位置更新时都会有一个动画,但现在有一个概念证明,我可以更新位置并通过按下按钮来启动动画

我的第一种方法是使用 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>

到目前为止,这是我的视图模型。显然缺少对 ActionCommand 的 Binding,并且 ActionCommand 也应该更改 CanAnimate 以便再次触发 Animation,但由于 CanAnimate 为 true,它仍应设置一次动画:

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));
            }
        }
    }

}

提前致谢!

4

0 回答 0