8

我正在尝试调整一个简单的 WPF 应用程序以使用 Model-View-ViewModel 模式。在我的页面上,我有几个动画:

<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>

目前我在后面的代码中开始动画,并且可以在完成时监听 Co​​mpleted 事件以执行以下代码:

storyboardRight = (Storyboard)TryFindResource("storyboardRight");
storyboardRight.Completed += new EventHandler(storyboardRight_Completed);
storyboardRight.Begin(this);

有没有办法将故事板数据绑定到我的 ViewModel,以便它从 ViewModel 引发的事件开始,并在完成时回调到该 ViewModel?

4

3 回答 3

9

我有机会向微软的 Josh Twist 提出这个问题,他很乐意花时间提供这个问题的答案。解决方案是结合 ViewModel 中的枚举使用 aDataTrigger来启动 Storyboard,而这又需要将页面放入ContentPresenter. 为了处理动画完成,需要少量代码来调用ICommandViewModel 上的 an。

在此处阅读 Josh 的帖子,了解该解决方案的完整描述。

于 2008-12-31T11:12:55.323 回答
2

我通过使用 DataTrigger 并将其绑定到我的 ViewModel 中的属性来做到这一点。当“FlashingBackGround”属性设置为“ON”时,情节提要动画开始。

还要确保在您的项目中包含对“Microsoft.Expression.Interactions”的引用

XAML:(这直接在根节点中)

<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>

视图模型:

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

最后,Viewmodel 必须继承自“INotifyPropertyChanged”

于 2011-05-12T15:54:42.230 回答
1

您需要使用EventTrigger. 这篇关于 WPF 中动画的文章可能会有所帮助。另请参阅MSDN 上的Routed Events Overview和How to: Use Event Triggers to Control a Storyboard After Starts

于 2008-11-13T13:48:56.703 回答