Применение анимаций раскадровки к нескольким объектам XAML

Applies to Windows and Windows Phone

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

Рассмотрим страницу XAML из приложения с сеткой изображений дополнительной клавиатуры. Когда пользователь нажимает одну из кнопок, к ней должна применяться анимация, создавая иллюзию движения.

Файл XAML с несколькими кнопками: вы действительно хотите создать анимацию раскадровки для каждой кнопки?

Как было показано в разделе Применение обложки и анимации к кнопке, в отличие от iOS, где параметры, например непрозрачность, динамически меняются в блоке анимации, Windows 8 использует объекты раскадровки. Если на экране должно отображаться несколько аналогичных объектов XAML, таких как наша сетка кнопок, нужно ли создавать отдельную раскадровку для каждого объекта? К счастью, нет. И далее мы расскажем, как применить одну и ту же анимацию к нескольким объектам.

Примечание   Напоминаем, что в Windows 8 раскадровка — это анимация, а не способ создания макета приложения, как в Xcode.

Секрет заключается в программном изменении свойства TargetName раскадровки, как показано в следующем примере.

Определение раскадровки

Во-первых, определите анимацию раскадровки. Вы можете либо воспользоваться Blend, либо определить ее вручную в XAML. Пример использования Blend можно найти в разделе Применение обложки и анимации к кнопке. Если вы используете Blend, удалите свойство TargetName, иначе анимация будет применяться только к данному конкретному целевому объекту. Пример:


    <Page.Resources>
        <Storyboard x:Name="TapAnimation">
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
		</Storyboard>
    </Page.Resources>

Не забывайте добавлять тег <RenderTransform> в любой объект XAML, который будет изменять ваша раскадровка, а также заполнитель для конкретного преобразования, анимирование которого выполняется. В противном случае ваше приложение вызовет исключение. Вот пример объекта Image, готового к применению раскадровки:


 <Image x:Name="myImage" Width="256" Height="160" RenderTransformOrigin= "0.5,0.5" >
                        <Image.RenderTransform>
                            <CompositeTransform/>
                        </Image.RenderTransform>
                    </Image>

Примечание  Благодаря использованию свойства RenderTransformOrigin= "0.5,0.5" анимация будет сосредоточена вокруг центра объекта.

Применение раскадровки

Далее свяжите раскадровку с объектом и запустите ее. Нужно сделать одну оговорку: свойство TargetName нельзя изменить во время воспроизведения анимации, иначе приложение вызовет исключение. Чтобы избежать этого, вызовите Stop() до изменения целевого объекта.

Совет  Вызов GetCurrentState() позволяет определить, выполняется ли в настоящий момент раскадровка.

Далее приведен код, запускающий анимацию для конкретного объекта Image. Например, этот код может срабатывать, когда пользователь касается изображения, вызывая событие PointerPressed. Данный код так же легко применить к объекту Button, используя событие Click.


 // Add using Windows.UI.Xaml.Media.Animation;
            TapAnimation.Stop();
            TapAnimation.SetValue(Storyboard.TargetNameProperty,"myImage");
            TapAnimation.Begin();

Такой подход еще полезнее применять, когда новое имя целевого объекта автоматически создается из элемента управления, вызвавшего событие, как показано в следующем примере:


  private void someImages_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            TapImage.Stop();
            TapImage.SetValue(Storyboard.TargetNameProperty, (sender as Image).Name);
            TapImage.Begin();
        }

Здесь объект Image, которого коснулся пользователь, создает событие, и его имя используется в качестве целевого объекта. Если все изображения на странице при касании создают одно и то же событие, к ним будет применена одна и та же анимация раскадровки. Так, в нашем примере с дополнительной клавиатурой анимация будет применяться к каждой клавише и нам нужно будет создать лишь одну раскадровку.

Примечание  Возможно, раньше вы не видели как клавиатуру: она выполняет приведение типа отправителя для преобразования его в объект Image.

Несколько кнопок, один обработчик событий

Если приложение содержит несколько аналогичных кнопок, разумно иметь один главный обработчик событий, а не создавать обработчик для каждой кнопки. Каждая кнопка может использовать одно и то же событие нажатия, но нужен способ различать кнопки в коде: здесь как раз уместно использовать tags.

Как и в iOS, у каждого элемента управления или объекта может быть тег — значение, которое уникальным образом их идентифицирует. В примере с дополнительной клавиатурой можно определить кнопки, как в этом коде XAML: обратите внимание, что кнопки практически идентичны, но различаются значениями тега.


	<Button Content="1" HorizontalAlignment="Left" Margin="446,78,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="1">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="2" HorizontalAlignment="Left" Margin="446,543,0,0" VerticalAlignment="Top" Width="460" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="2">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="3" HorizontalAlignment="Left" Margin="446,393,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="3">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>

Все кнопки указывают на один и тот же обработчик событий — Button_Click. Можно считать значение тега и выполнить соответствующие действия в обработчике следующим образом:


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var tag = (sender as Button).Tag;

            int t = Convert.ToInt16(tag);

            switch (t)
            {
                case 0: break;
                case 1: break;
                case 2: break;
                default: break;
            }
        }

Связанные разделы

Программная обработка анимаций
Приступая к работе: анимация
Практическое руководство: создание пользовательских интерфейсов с использованием XAML и Expression Blend
Раскадрованные анимации

 

 

Показ:
© 2014 Microsoft