Главная » Разработка для Windows Phone 7 » Анимации, описанные в XAML

0

Бытует мнение, что раскадровки и анимации проще описывать в XAML, чем в коде, поэтому в большинстве случаев анимации Silverlight описываются в XAML. Но тогда возникают некоторые трудности в связи с совместным использованием ресурсов.

Перепишем приложение ClickAndSpin, определяя раскадровки и анимации в XAML. Рассмотрим область содержимого приложения XamlClickAndSpin:

Проект Silverlight: XamlClickAndSpin Файл: MainPage.xaml (фрагмент)

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions>

<RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions>

<Button Name="btn1"

Content="Button No. 1" Grid.Row="0"

HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5 0.5" Click="OnButtonClick"> <Button.RenderTransform>

<RotateTransform x:Name="rotate1" /> </Button.RenderTransform> </Button>

<Button Name="btn2"

Content="Button No. 2" Grid.Row="1"

HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5 0.5" Click="OnButtonClick"> <Button.RenderTransform>

<RotateTransform x:Name="rotate2" /> </Button.RenderTransform> </Button>

<Button Name="btn3"

Content="Button No. 3" Grid.Row="2"

HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5 0.5" Click="OnButtonClick"> <Button.RenderTransform>

<RotateTransform x:Name="rotate3" /> </Button.RenderTransform> </Button> </Grid>

Данная разметка практически аналогична предыдущей версии за исключением того, что всем элементам Button и всем объектам RotateTransform были присвоены имена для упрощения ссылки на них.

Раскадровки и анимации определены в коллекции Resources страницы: Проект Silverlight: XamlClickAndSpin Файл: MainPage.xaml (фрагмент)

<phone:PhoneApplicationPage.Resources> <Storyboard x:Name="storyboard1">

<DoubleAnimation Storyboard.TargetName="rotate1"

Storyboard.TargetProperty="Angle" From="0" To="3 60" Duration="0:0:0.5" />

</Storyboard>

<Storyboard x:Name="storyboard2">

<DoubleAnimation Storyboard.TargetName="rotate2"

Storyboard.TargetProperty="Angle" From="0" To="3 60" Duration="0:0:0.5" />

</Storyboard>

<Storyboard x:Name="storyboard3">

<DoubleAnimation Storyboard.TargetName="rotate3"

Storyboard.TargetProperty="Angle" From="0" To="3 60" Duration="0:0:0.5" />

</Storyboard> </phone:PhoneApplicationPage.Resources>

Три кнопки – три раскадровки. Обратите внимание на присоединенные свойства:

<DoubleAnimation Storyboard.TargetName="rotate1"

Storyboard.TargetProperty="Angle" From="0" To="3 60" Duration="0:0:0.5" />

Для задания присоединенных свойств в коде вызываются статические методы Storyboard.SetTarget и Storyboard.SetTargetProperty. В XAML мы задаем присоединенные свойства Storyboard.TargetName (Имя цели) и Storyboard.TargetProperty. Заметьте разницу: в разметке ссылка на целевой объект происходит по имени, тогда как доступ в коде выполняется непосредственно к самому объекту.

Как альтернативный вариант ссылка на свойство Angle может быть сделана через объект Button:

<DoubleAnimation Storyboard.TargetName="btn1"

Storyboard.TargetProperty="(Button.RenderTransform).(RotateTransform.Angle)" From="0" To="3 60" Duration="0:0:0.5" />

Или :

<DoubleAnimation Storyboard.TargetName="btn1"

Storyboard.TargetProperty="(Button.RenderTransform).Angle" From="0" To="3 60" Duration="0:0:0.5" />

При таком синтаксисе объектам RotateTransform имена не требуются.

Обратите внимание на задание продолжительности. Требуется по крайней мере три числа, определяющих часы, минуты и секунды, разделенные двоеточиями. У секунд может быть дробная часть. Перед значением часов может быть указано количество дней; значения дней и часов разделяются точкой.

Чтобы было проще ссылаться на ресурсы Storyboard из кода, я использовал x:Name, а не x:Key. Обработчик события Click кнопки просто вызывает Begin соответствующего объекта:

Проект Silverlight: XamlClickAndSpin Файл: MainPage.xaml.cs (фрагмент)

void OnButtonClick(object sender, RoutedEventArgs args) {

if (sender == btn1)

storyboard1.Begin();

else if (sender == btn2)

storyboard2.Begin();

else if (sender == btn3) storyboard3.Begin();

}

Все достаточно просто. Но, вероятно, я не одинок в желании иметь возможность описывать в XAML всего одну раскадровку и анимацию, а не три. Кажется возможным опустить присвоение Storyboard.TargetName в XAML и вызывать метод Storyboard.SetTarget в коде, как только становится известным, какая кнопка нажата. Но мы не можем обеспечить совместного использования ресурсов, и если конкретные Storyboard и DoubleAnimation ассоциированы с одним Button, они не могут использоваться с другим Button. Имея один ресурс Storyboard и DoubleAnimation, мы не можем заставить вращаться две кнопки одновременно.

Даже если предположить, что одна кнопка будет останавливаться до начала вращения второй, мы должны гарантированно обеспечить остановку выполнения раскадровки, т.е. обязательно вызвать метод Stop объекта Storyboard. (Кроме методов Begin и Stop класс Storyboard описывает также методы Pause (Приостановить) и Resume (Возобновить), но они используются нечасто.)

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии