如何在 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 DoubleAnimationTo 值,但为此我需要获取 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);
    }
}