Анимация Object в WinRT

112

Система анимации Windows Runtime также способна анимировать свойства типа Object. Казалось бы, эта возможность включает в себя все остальные, но не все так просто: класса ObjectAnimation со свойствами From и To не существует. Есть только класс ObjectAnimationUsingKeyFrames, и единственным классом, производным от ObjectKeyFrame, является DiscreteObjectKeyFrame.

Иначе говоря, вы действительно можете определить анимацию для свойства любого типа (при условии, что оно поддерживается свойством зависимости), но анимация может использоваться только для задания этому свойству дискретных значений.

На практике объектные анимации используются в основном для свойств перечислимых типов или типов Brush, позволяющих задать свойству предопределенный ресурс кисти. Чаще всего они используются в шаблонах элементов управления. Однако в следующем примере, в котором объект Ellipse перемещается по экрану с анимацией Visibility значениями из перечисления Visible и Collapsed, a Fill - предопределенными кистями:

<Page ...>

    <Grid Background="Gray">
        <Canvas SizeChanged="Canvas_SizeChanged"
                Margin="0 0 96 96">
            <Ellipse Name="ellipse"
                     Width="96"
                     Height="96" />
        </Canvas>
    </Grid>

    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation x:Name="horzAnimation"
                                     Storyboard.TargetName="ellipse"
                                     Storyboard.TargetProperty="(Canvas.Left)"
                                     From="0" Duration="0:0:2.51"
                                     AutoReverse="True"
                                     RepeatBehavior="Forever" />

                    <DoubleAnimation x:Name="vertAnimation"
                                     Storyboard.TargetName="ellipse"
                                     Storyboard.TargetProperty="(Canvas.Top)"
                                     From="0" Duration="0:0:1.01"
                                     AutoReverse="True"
                                     RepeatBehavior="Forever" />

                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ellipse"
                                        Storyboard.TargetProperty="Visibility"
                                        RepeatBehavior="Forever">
                        <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="Collapsed" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.25" Value="Visible" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="Collapsed" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.45" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ellipse"
                                        Storyboard.TargetProperty="Fill"
                                        RepeatBehavior="Forever">
                        <DiscreteObjectKeyFrame KeyTime="0:0:0" 
                            Value="{StaticResource ApplicationPageBackgroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.2" 
                            Value="{StaticResource ApplicationForegroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.4" 
                            Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.6" 
                            Value="{StaticResource ApplicationPageBackgroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>

</Page>

Интересно, что свойству Value объекта DiscreteObjectKeyFrame можно задать непосредственно имя элемента перечисления или StaticResource, и это не вызовет никакой путаницы с типом.

Другое преимущество определения Storyboard и анимаций в секции Triggers - возможность обращения к анимациям по имени в файле фонового кода:

private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
    horzAnimation.To = e.NewSize.Width;
    vertAnimation.To = e.NewSize.Height;
}
Пройди тесты
Лучший чат для C# программистов