如何控制 VisualState 中 Storyboard 的 SpeedRatio?

Posted

技术标签:

【中文标题】如何控制 VisualState 中 Storyboard 的 SpeedRatio?【英文标题】:How can I control the SpeedRatio of a Storyboard inside a VisualState? 【发布时间】:2011-03-31 00:19:59 【问题描述】:

给定一个由 VisualStateManager 启动的 Storyboard 作为 ControlTemplate 的一部分,我将如何根据控件的属性更改调整该动画的 SpeedRatio?

<ControlTemplate>
  <Grid>
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup>
        <VisualState>
          <Storyboard Name="SpinningThing"
                      SpeedRatio="Binding SpinningSpeedRatio">
            ...

这需要在 WPF 和 Silverlight 中都有效。

出于多种原因,我认为我不能在那里设置绑定。最重要的是,Storyboard 是可冻结的,因此您不能在 WPF 中随意设置 SpeedRatio。但是,如果它是由 VisualStateManager 启动的,我可以在上面调用 SetSpeedRatio 吗?

另外,由于它的父级是 VisualState,这是否意味着不存在与之相关的管理 FrameworkElement?

那么,如果我不能通过绑定来做到这一点,那该怎么做呢?

【问题讨论】:

【参考方案1】:

对于那些来这里寻找 UWP 解决方案的人,您可以StoryboardSpeedRatio 属性上使用 x:Bind,它确实可以动态更改速度比,正如您所期望的那样.

<Storyboard SpeedRatio="x:Bind ViewModel.SpinningSpeedRatio, Mode=OneWay">

编辑:需要注意的是,您需要确保在UIThread 上设置比率,否则VisualStateManager 将忽略它。 Storyboard 仍会播放,但不会以您设置的速度播放。

【讨论】:

【参考方案2】:

通常您会使用 TemplateBinding... 而不是 Binding...,但这仅适用于简单、兼容的类型。

您还应该能够使用"relative binding source" 绑定到模板化控件。如果类型不匹配,这也允许您使用值转换器。

SpeedRation=Binding SomeProperty, RelativeSource=RelativeSource TemplatedParent, Converter=StaticResource SomeConverter" 

我没有在 WPF 中测试过,但 Silverlight 通常是功能受限的。

【讨论】:

不幸的是,WPF 是简单的答案分崩离析的地方。在 WPF 中,时间线是 Freezable 对象,因此绑定不会更改 SpeedRatio 的实际值。 msdn.microsoft.com/en-us/library/… 另外,因为它处于 ViewState(我猜),您会收到绑定错误消息“找不到用于绑定的管理 FrameworkElement...”。【参考方案3】:

好吧,看起来确实没有办法通过绑定来严格处理这个问题。因此,为了解决这个问题,我在代码隐藏中添加了一些事件,以根据需要启动/调整动画。

【讨论】:

以上是关于如何控制 VisualState 中 Storyboard 的 SpeedRatio?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过XAML,WPF中的数据绑定设置VisualState INITIALIZATION

如何通过Behavior和VisualStateManager将TextBox设置为特定的内置VisualState

[UWP]了解模板化控件(5.1):TemplatePart vs. VisualState

控件 UI: VisualState, VisualStateManager, 控件的默认 UI

不修改模板的前提下修改VisualState中的某些值

[UWP] [VisualState]自定义ListViewItem悬停演示文稿