如何在 Windows 8.1 (WinRT) 中访问 Storyboard
How to access Storyboard in Windows 8.1 (WinRT)
在我的 xaml 文件中我有:
<Grid x:Name="LayoutRoot"...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WebformSizeState">
<VisualState x:Name="MaximizedSizeState">
<Storyboard x:Name="MaximizeSizeStory">
<DoubleAnimation Duration="0:0:0.3" To="-120" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="WebpageContainer"/>
</Storyboard>
</VisualState>
...
<ec:DataTriggerBehavior Value="2" Binding="{Binding WebpageSizeState, Converter={StaticResource EnumToIntegerConverter}}">
<ec:GoToStateAction StateName="MaximizedSizeState"/>
</ec:DataTriggerBehavior>
...
代码按原样运行。如果 WebpageSizeState
获得 2
的 in 值,则 WebpageContainer
向上移动 120。
我想以编程方式更改代码隐藏文件中 Storyboard DoubleAnimation
的 To
值,但为此我需要获取 Storyboard(我假设).
我尝试过但失败的事情:
尝试 1
根据 MSDN documentation,直接访问应该可以,但如果我尝试分配值:
Storyboard maximizeSizeStory = MaximizeSizeStory;
则 maximizeSizeStory 为 null
并在 Watch 窗口中查看,MaximizeSizeStory
也为空。
尝试 2
正在为 DoubleAnimation
分配名称并尝试直接访问它:
<DoubleAnimation x:Name="MaximizeAnimation" ../>
当 ViewModel 中的 DataTrigger 绑定发生更改时,这会导致应用崩溃并出现空引用异常。
哦,是的,后面代码中的值也是 null
。
尝试 3
使用 UID
查找元素,就像在 this question 中所做的那样:
你不能,因为 UIElement and DependencyObject 不再定义 UID。
并且 Storyboard 不是 UIElement,我认为这是使用 FindName
的原因
Storyboard sb = this.FindName("MaximizeSizeStory") as Storyboard;
也returns空。
尝试 4
无法通过 Key
访问它,因为它未在 Page.Resources
或字典中定义。
如果你尝试在 Page.Resources
中声明它,它会给出错误:
A property element cannot be the direct content of another property element.
Nested properties are not supported: VisualStateManager.VisualStateGroups.
我很茫然,有什么想法吗?
这是一种方法(为清楚起见简化了示例)。注意 VisualStateManager.GetVisualStateGroups 的使用,因为故事板在其中:
<Grid x:Name="LayoutRoot" Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyGroups">
<VisualState x:Name="MyStates">
<Storyboard x:Name="MyAnimation">
<ColorAnimation Duration="0" To="Yellow" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="rectangle" Height="50" Width="50" Fill="red"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" Content="Click me" Click="Button_Click" />
</Grid>
以及按钮处理程序的代码,我们实际访问情节提要的地方:
private void Button_Click(object sender, RoutedEventArgs e)
{
var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot)[0].States[0].Storyboard;
storyboard.Begin();
}
添加一些扩展可以使代码更易读并且更不容易出错:
public sealed partial class SomePage
{
void SomeMethod()
{
var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot).Get("MyGroups").States.Get("MyStates").Storyboard;
}
}
public static class StateExtensions
{
public static VisualStateGroup Get(this IList<VisualStateGroup> stateGroups, string name)
{
return stateGroups.Single(x => x.Name == name);
}
public static VisualState Get(this IList<VisualState> stateGroups, string name)
{
return stateGroups.Single(x => x.Name == name);
}
}
在我的 xaml 文件中我有:
<Grid x:Name="LayoutRoot"...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WebformSizeState">
<VisualState x:Name="MaximizedSizeState">
<Storyboard x:Name="MaximizeSizeStory">
<DoubleAnimation Duration="0:0:0.3" To="-120" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="WebpageContainer"/>
</Storyboard>
</VisualState>
...
<ec:DataTriggerBehavior Value="2" Binding="{Binding WebpageSizeState, Converter={StaticResource EnumToIntegerConverter}}">
<ec:GoToStateAction StateName="MaximizedSizeState"/>
</ec:DataTriggerBehavior>
...
代码按原样运行。如果 WebpageSizeState
获得 2
的 in 值,则 WebpageContainer
向上移动 120。
我想以编程方式更改代码隐藏文件中 Storyboard DoubleAnimation
的 To
值,但为此我需要获取 Storyboard(我假设).
我尝试过但失败的事情:
尝试 1
根据 MSDN documentation,直接访问应该可以,但如果我尝试分配值:
Storyboard maximizeSizeStory = MaximizeSizeStory;
则 maximizeSizeStory 为 null
并在 Watch 窗口中查看,MaximizeSizeStory
也为空。
尝试 2
正在为 DoubleAnimation
分配名称并尝试直接访问它:
<DoubleAnimation x:Name="MaximizeAnimation" ../>
当 ViewModel 中的 DataTrigger 绑定发生更改时,这会导致应用崩溃并出现空引用异常。
哦,是的,后面代码中的值也是 null
。
尝试 3
使用 UID
查找元素,就像在 this question 中所做的那样:
你不能,因为 UIElement and DependencyObject 不再定义 UID。
并且 Storyboard 不是 UIElement,我认为这是使用 FindName
Storyboard sb = this.FindName("MaximizeSizeStory") as Storyboard;
也returns空。
尝试 4
无法通过 Key
访问它,因为它未在 Page.Resources
或字典中定义。
如果你尝试在 Page.Resources
中声明它,它会给出错误:
A property element cannot be the direct content of another property element. Nested properties are not supported: VisualStateManager.VisualStateGroups.
我很茫然,有什么想法吗?
这是一种方法(为清楚起见简化了示例)。注意 VisualStateManager.GetVisualStateGroups 的使用,因为故事板在其中:
<Grid x:Name="LayoutRoot" Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyGroups">
<VisualState x:Name="MyStates">
<Storyboard x:Name="MyAnimation">
<ColorAnimation Duration="0" To="Yellow" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="rectangle" Height="50" Width="50" Fill="red"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" Content="Click me" Click="Button_Click" />
</Grid>
以及按钮处理程序的代码,我们实际访问情节提要的地方:
private void Button_Click(object sender, RoutedEventArgs e)
{
var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot)[0].States[0].Storyboard;
storyboard.Begin();
}
添加一些扩展可以使代码更易读并且更不容易出错:
public sealed partial class SomePage
{
void SomeMethod()
{
var storyboard = VisualStateManager.GetVisualStateGroups(this.LayoutRoot).Get("MyGroups").States.Get("MyStates").Storyboard;
}
}
public static class StateExtensions
{
public static VisualStateGroup Get(this IList<VisualStateGroup> stateGroups, string name)
{
return stateGroups.Single(x => x.Name == name);
}
public static VisualState Get(this IList<VisualState> stateGroups, string name)
{
return stateGroups.Single(x => x.Name == name);
}
}