WPF VisualStateManager 动画绑定
我在 Button.Trigger 中使用简单的 DoubleAnimation。动画起始点绑定到根元素 ActualHeight。这按预期工作。
接下来,我尝试将 Storyboard 移至 VisualStateManager。现在 WPF 抱怨:
System.Windows.Data 错误:2:找不到目标元素的控制 FrameworkElement 或 FrameworkContentElement。 BindingExpression:路径=实际宽度;数据项=空;目标元素是“DoubleAnimation”(HashCode=29201322);目标属性是“To”(类型“Nullable`1”)
是否无法在 VisualStateManager.VisualStateGroups/VisualState 内的动画中使用绑定?
看来不是。我通过将故事板移至资源来解决该问题。所以现在 GameToTitle 可以工作,而 TitleToGame 将失败。
我仍然很高兴知道这是否是预期的。
相关XAML:
<Grid x:Name="MainInterface">
<Grid.Resources>
<Storyboard x:Key="GameToTitle">
<DoubleAnimation Storyboard.TargetName="GameScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="0" To="{Binding Path=ActualHeight, ElementName=MainInterface}" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="TitleScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="{Binding Path=ActualHeight, ElementName=MainInterface, Converter={Converters:InverseConverter}}" To="0" Duration="0:0:0.2"/>
</Storyboard>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="TitleScreenState" Storyboard="{StaticResource ResourceKey=GameToTitle}"/>
<VisualState x:Name="GameScreenState">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="GameScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="{Binding Path=ActualHeight, ElementName=MainInterface}" To="0" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="TitleScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="0" To="{Binding Path=ActualHeight, ElementName=MainInterface, Converter={Converters:InverseConverter}}" Duration="0:0:0.2"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<View:TitleScreen x:Name="TitleScreenInterface"/>
<View:GameScreen x:Name="GameScreenInterface" />
</Grid>
I'm using a simple DoubleAnimation in Button.Trigger. Animation From is bound to root element ActualHeight. This works as expected.
Next I've tried to move the Storyboard to VisualStateManager. Now WPF complains:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=ActualWidth; DataItem=null; target element is 'DoubleAnimation' (HashCode=29201322); target property is 'To' (type 'Nullable`1')
Is it not possible to use bindings in animations within the VisualStateManager.VisualStateGroups/VisualState ?
It seems not. I fixed the problem by moving the storyboard to resources. So now GameToTitle will work while TitleToGame will fail.
I'd still appreciate to know if this is expected or not.
Relevant XAML:
<Grid x:Name="MainInterface">
<Grid.Resources>
<Storyboard x:Key="GameToTitle">
<DoubleAnimation Storyboard.TargetName="GameScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="0" To="{Binding Path=ActualHeight, ElementName=MainInterface}" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="TitleScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="{Binding Path=ActualHeight, ElementName=MainInterface, Converter={Converters:InverseConverter}}" To="0" Duration="0:0:0.2"/>
</Storyboard>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="TitleScreenState" Storyboard="{StaticResource ResourceKey=GameToTitle}"/>
<VisualState x:Name="GameScreenState">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="GameScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="{Binding Path=ActualHeight, ElementName=MainInterface}" To="0" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="TitleScreenInterface" Storyboard.TargetProperty="(Control.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)" From="0" To="{Binding Path=ActualHeight, ElementName=MainInterface, Converter={Converters:InverseConverter}}" Duration="0:0:0.2"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<View:TitleScreen x:Name="TitleScreenInterface"/>
<View:GameScreen x:Name="GameScreenInterface" />
</Grid>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如问题的评论所指出的,包含绑定的 Storyboard 必须声明为资源,而不是在 VisualStateGroup 内内联才能使绑定起作用。这是因为 VisualStates 不是 VisualTree 的一部分。另一方面,资源是。
您可以使用 Snoop(或类似的实用程序)查看应用程序的可视化树,亲自将其可视化。您会注意到资源节点出现在 Snoop 内的可视化树中,但 VisualStates 却没有。
As the question's comments note, Storyboards containing bindings must be declared as resources instead of inline within the VisualStateGroup for the bindings to work. This is due to the fact that VisualStates aren't part of the VisualTree. Resources, on the other hand, are.
You can visualize this for yourself by using Snoop (or similar utility) to look at the visual tree of your application. You'll notice that Resources nodes appear in the visual tree within Snoop, but VisualStates do not.