如何控制 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 解决方案的人,您可以在 Storyboard
的 SpeedRatio
属性上使用 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