1

我的视图中有一个简单的Border元素,它带有一个TextBlock绑定到表示我的应用程序中进程状态的字符串的子元素。

我正在尝试为该边框设置动画,以便在TextBlock修改绑定到的字符串时滑入以从屏幕外查看。

这是我到目前为止所拥有的:

<Border>
    <Border.Triggers>
        <EventTrigger RoutedEvent="Binding.TargetUpdated">
            <BeginStoryboard>
                <Storyboard>
                    <ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,-100,0,0" To="0,0,0,0" DecelerationRatio=".9" Duration="0:0:1" />
                    <ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,0,0,0" To="0,-100,0,0" AccelerationRatio=".9" BeginTime="0:0:5" Duration="0:0:1" />
                </Storyboard>
            </BeginStoryBoard>
        </EventTrigger>
    </Border.Triggers>
    <TextBlock Text="{Binding StatusText, Mode=OneWay, NotifyOnTargetUpdated=True}"></TextBlock>
</Border>

这按预期工作,但有两个问题我不知道如何解决:

  1. 每当文本更改我不想要这个时,动画就会重新开始。我想要的是在它滑开之前等待 5 秒以重新启动。因此,如果文本不断更新,那么面板应该保持静止,直到距离上次更新超过 5 秒,然后向上滑动。
  2. 当应用程序启动时,动画会立即播放。我猜是因为初始绑定算作更新。我怎样才能阻止这种情况发生?
4

1 回答 1

0

考虑到您的数据在 ViewModel 中,对于问题1 ,我建议使用DispatcherTimer每次StatusText更改时都会重新启动的 a(您应该使用INotifyPropertyChanged它)。将 设置DispatcherTimer.Interval为 5000 毫秒,当它滴答时开始动画以将边框滑出屏幕。

现在的问题是,因为您使用的是 MVVM,所以我知道应用动画的唯一方法非常复杂。

因此,要手动应用动画(不是来自 XAML,而是来自 ViewModel),我建议创建一个继承自 Border 的自定义控件类,然后在 XAML 中创建自定义控件类的一个实例,最后触发“滑出屏幕" 来自自定义控件类的动画。

要从 ViewModel 触发动画(位于自定义控件中),您可以在自定义控件类中有一个DependencyProperty类型,当设置为 true 时将触发动画(在动画开始后立即更改依赖属性的值bool为 false 以便稍后可以通过再次将值更改为 true 来再次触发它)。触发动画的绑定使用TowWaymode 非常重要,以便在动画启动时也将 ViewModel 中的属性设置回 false。所以从技术上讲,视图模型中的 bool 属性将作为一个开关,在您翻转它后会立即自动关闭(类似于 Minecraft 中的按钮和控制杆)。

要解决问题2,只需保留另一个bool变量作为标志,以避免StatusText在第一次更改时触发动画。

PS:我知道问题1的解决方案很复杂,但到目前为止,这是我发现在不破坏 MVVM 的情况下从 ViewModel 触发动画的唯一方法。

于 2016-04-15T15:44:38.730 回答