- •1. Вводная часть
- •2. Знакомство со средой разработки на примере создания простого консольного приложения
- •3. Модификация консольного приложения
- •4. Публикация
- •5. О приложении к Лабораторной работе № 1
- •Лабораторная работа № 2: Создание простого приложения Windows Forms
- •Создание простого приложения Windows Forms
- •Модификация приложения Windows Forms
- •Завершающая часть
- •2. Создание простого приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Завершающая часть
- •5. О приложении к Лабораторной работе № 2
- •3. Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления Лабораторная работа № 3: Windows Forms и использование некоторых элементов управления
- •Вводная часть
- •О приложении к Лабораторной работе № 3
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: элемент управления MenuStrip
- •5. Модификация приложения Windows Forms: элемент управления Button
- •6. Модификация приложения Windows Forms: элемент управления ToolTip
- •7. Модификация приложения Windows Forms: элемент управления ComboBox
- •8. Модификация приложения Windows Forms: элемент управления WebBrowser
- •9. Модификация приложения Windows Forms: добавляем исходный код
- •10. Завершающая часть
- •11. О приложение к Лабораторной работе № 3
- •4. Лабораторная работа № 4: Windows Forms — работа с формами Лабораторная работа № 4: Windows Forms — работа с формами
- •Вводная часть
- •О приложении к Лабораторной работе № 4
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: добавление новой формы
- •5. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через прямой доступ к элементу формы
- •6. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через передачу метода в конструктор формы
- •7. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через класс делегата
- •8. Модификация приложения Windows Forms: динамическое связывание параметров двух форм и передача параметра через свойства
- •9. Завершающая часть
- •10. О приложении к Лабораторной работе № 4
- •5. Лабораторная работа № 5: Windows Forms — элементы управления Лабораторная работа № 5: Windows Forms — элементы управления
- •Вводная часть
- •О приложении к Лабораторной работе № 5
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms
- •4. Модификация приложения Windows Forms: динамическое добавление и уничтожение элемента управления
- •5. Модификация приложения Windows Forms: стандартные диалоговые окна
- •6. Модификация приложения Windows Forms: открытие файла, сохранение файла и работа с текстом
- •7. Модификация приложения Windows Forms: прочее
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 5
- •Лабораторная работа № 6: SolidWorks — работа с SolidWorks
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: eDrawings 2012
- •4. Модификация приложения Windows Forms: организация работы с SolidWorks через приложение
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 6
- •Лабораторная работа № 7: SolidWorks — использование SwCSharpAddin, работа с макросом и шаблоном детали
- •2. Создание приложения SwCSharpAddin
- •3. Модификация приложения SwCSharpAddin: макрос отрисовки болта
- •4. Модификация приложения SwCSharpAddin: построение через шаблон детали
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 7
- •8. Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation Лабораторная работа № 8: Создание простого приложения Windows Foundation Presentation
- •Вводная часть
- •О приложении к Лабораторной работе № 8
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: добавление нового элемента из библиотеки компонентов wpf
- •5. Модификация приложения Windows Forms: расширение функциональности приложения и работа с оформление
- •6. Модификация приложения Windows Foundation Presentation: различные возможности wpf
- •7. Модификация приложения Windows Foundation Presentation: немного о стилях и шаблонах
- •8. Завершающая часть
- •9. О приложении к Лабораторной работе № 8
- •Лабораторная работа № 9: Создание приложения-презентации Windows Foundation Presentation
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation
- •4. Модификация приложения Windows Foundation Presentation: работа с решением в Expression Blend
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 9
- •Лабораторная работа № 10: Работа с базами данных — xml и ole
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: odbc
- •4. Модификация приложения Windows Forms: ole
- •5. Модификация приложения Windows Forms: xml
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 10
- •Лабораторная работа № 11: Динамическая связь приложений через библиотеку классов
- •2. Удалённый объект: создание библиотеки классов удалённого объекта
- •3. Клиент: создание приложения Windows Forms
- •4. Сервер: создание консольного приложения
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 11
- •Лабораторная работа № 12: Автоматизация Microsoft Office Word
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Word
- •4. Модификация приложения Windows Forms: работа с шаблонами
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 12
- •Лабораторная работа № 13: Автоматизация Microsoft Office Excel
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: создание и заполнение нового документа Microsoft Excel
- •4. Модификация приложения Windows Forms: чтение данных с документа Microsoft Excel
- •5. Модификация приложения Windows Forms: прочие возможности Microsoft Excel
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 13
- •Лабораторная работа № 14: Простой растровый редактор
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора
- •4. Модификация приложения Windows Forms: функциональность растрового редактора
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 14
- •15. Лабораторная работа № 15: Векторный редактор изображений Лабораторная работа № 15: Векторный редактор изображений
- •Вводная часть
- •О приложении к Лабораторной работе № 15
- •1. Вводная часть
- •2. Создание решения, приложения Windows Forms и библиотеки классов
- •3. Модификация приложения Windows Forms: подготовка интерфейса редактора и добавление файлов ресурсов
- •4. О будущей функциональности векторного редактора изображений
- •5. Модификация приложения Windows Forms: подготовка библиотеки классов
- •6. Модификация приложения Windows Forms: функциональность векторного редактора
- •7. Завершающая часть
- •8. О приложении к Лабораторной работе № 15
- •Лабораторная работа № 16: Windows Communication Foundation
- •2. Создание приложения wcf:
- •3. Модификация приложения wcf: приложение-клиент для wcf-службы
- •4. Создание приложения Windows Forms: сервер чата на wcf
- •5. Создание приложения Windows Forms: клиент чата на wcf
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 16
- •Лабораторная работа № 17: Знакомство с Silverlight
- •2. Создание приложения Silverlight:
- •3. Модификация приложения Silverlight: первые шаги и полноэкранный режим
- •4. Модификация приложения Silverlight: простой проигрыватель mp3-файлов
- •5. Модификация приложения Silverlight: работа с анимацией
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 17
- •Лабораторная работа № 18: Знакомство с asp.Net
- •2. Создание веб-приложения asp.Net
- •3. Модификация веб-приложения asp.Net: реализация различной функциональности
- •4. Модификация веб-приложения asp.Net: ajax
- •5. Завершающая часть
- •6. О приложении к Лабораторной работе № 18
- •Вводная часть
- •О приложении к Лабораторной работе № 19
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: подготовка интерфейса и добавление TabControl
- •4. Модификация приложения Windows Forms: вкладка «Просто фон!»
- •5. Модификация приложения Windows Forms: вкладка «Объекты и градиент»
- •6. Модификация приложения Windows Forms: вкладка «Мой монитор сломался!»
- •7. Модификация приложения Windows Forms: вкладка «Векторные часы»
- •8. Модификация приложения Windows Forms: вкладка «Огонь!!!»
- •9. Модификация приложения Windows Forms: вкладка «Дождик»
- •10. Завершающая часть
- •11. О приложении к Лабораторной работе № 19
- •Лабораторная работа № 20: Inventor — работа с Inventor
- •Вводная часть
- •О приложении к Лабораторной работе № 20
- •1. Вводная часть
- •2. Создание приложения Windows Forms
- •3. Модификация приложения Windows Forms: запуск и завершение приложения Inventor
- •4. Модификация приложения Windows Forms: создание новых документов
- •5. Модификация приложения Windows Forms: доступ к элементам документов Inventor
- •6. Завершающая часть
- •7. О приложении к Лабораторной работе № 20
- •Лабораторная работа № 21: Знакомство с языком f# (Эф-шарп) на примере простого приложения для командной строки
- •Вводная часть
- •О приложении к Лабораторной работе № 21
- •1. Вводная часть
- •2. Основные положения при работе с f#
- •3. Создание приложения «Учебник по f#»
- •4. Создание консольного приложения
- •5. О приложении к Лабораторной работе № 21
- •Лабораторная работа № 22: Различные примеры на f#
- •2. Создание приложения «Приложение f#»
- •3. Модификация приложения f#: match
- •4. Модификация приложения f#: создание форм и рисование объектов на форме
- •5. Модификация приложения f#: работа с базой данных Microsoft Access
- •6. О приложении к Лабораторной работе № 22
- •23. Дополнительная лабораторная работа № 1
- •24. Дополнительная лабораторная работа № 2
- •25. Дополнительная лабораторная работа № 3
- •Вводная часть
- •1. Вводная часть
- •2. Создание приложения Windows Foundation Presentation
- •3. Модификация приложения Windows Foundation Presentation: добавление ресурсов
- •4. Модификация приложения Windows Foundation Presentation: добавление исходного кода
- •5. Модификация приложения Windows Foundation Presentation: оформление элемента ListBox
- •6. Завершающая часть
- •7. О приложении к данной работе
5. Модификация приложения Silverlight: работа с анимацией
Для работы с анимацией нужен объект анимации и объект, который будет анимирован. В нашем случаем таки объектом станет простой эллипс. Для «анимации» движения объекта в пространстве понадобится конечная точка движения, которую можно получить простым щелчком на странице в стороне от эллипса. Всё движение будет происходить от начальной до конечной точки, за время, определённое в коде.
Весь процесс анимации в основном в данной части работы, будет определять объект анимации:
<Storyboard>Дочерние анимации</Storyboard>
Storyboard — класс, шкала времени контейнера, которая предоставляет объект и свойство, содержащие сведения о дочерних анимациях.
Большая часть свойств шкалы времени могут иметь привязку данных или могут быть анимированы; тем не менее, в связи с особенностями действия системы расчета времени поведение привязанных к данным и анимированных шкал времени отличается от поведения других привязанных к данным или анимированных объектов. Чтобы понять их поведение, следует осознать, что означает активирование временной шкалы.
При активировании временной шкалы создаются копии временной шкалы и дочерних временных шкал. Эти копии фиксируются (устанавливаются в режим "только для чтения"), а на их базе создаются объекты Clock. Эти объекты используются для выполнения фактических действий по анимации целевых свойств. Если шкала времени является привязанной к данный или анимированной, при создании часов создается моментальный снимок ее текущих значений. Хотя исходная временная шкала может продолжить изменение, ее часы не будут меняться.
Для отражения в шкале времени привязки данных или изменений анимации необходимо повторно создать ее часы. Часы не воссоздаются автоматически. Ниже приведены несколько способов применения изменений шкалы времени:
Если шкала времени принадлежит Storyboard, можно заставить её отражать изменения посредством применения её раскадровки при помощи метода BeginStoryboard или Begin. Это имеет побочный эффект в виде перезапуска анимации. В коде можно использовать метод Seek для возврата раскадровки обратно в предыдущее положение.
Если анимация применяется непосредственно к свойству с помощью метода BeginAnimation, снова вызываем метод BeginAnimation и передаём ему измененную анимацию.
Если ведется работа непосредственно на уровне часов, создаём и применяем новый набор часов и используем их для замены предыдущего набора созданных часов.
Текст выше является выдержкой из статьи Storyboard - класс (http://msdn.microsoft.com/ru-ru/library/system.windows.media.animation.storyboard.aspx).
Подготовим «площадку» для реализации возможностей анимации. Откроем конструктор главной страницы MainPage.xaml и установим в единственную незанятую ячейку элемента Grid (строка: 4, столбец: 0) элемент TabControl ( ) со следующими свойствами, уже определёнными XAML-кодом:
<sdk:TabControl Grid.Row="4" HorizontalAlignment="Stretch" Name="tabControl1" VerticalAlignment="Stretch">
...
</sdk:TabControl>
Элемент TabControl будет растянут по всей ячейки элемента Grid. Что же касается кода на месте троеточия: там будет располагаться код определяющий закладки TabItem, но каждая закладка будет являться полноценной страницей XAML. Для первой закладки создаём эту страницу. Выделим имя WPF-проекта, далее выполним Проект -> Добавить новый элемент...: в открывшемся окне в списке «Установленные шаблоны» выберем «Silverlight», далее справа найдём «Страница Silverlight»:
Рис. 5. 1. Добавление нового элемента – LWP17Silverlight: Страница Silverlight
Имя вводим как Page_BasicAnimation.xaml (приставка Page нужна для группировки страниц в обозревателе решений). Жмём ОК. Страница добавлена. Откроем её в конструкторе и в коде XAML найдём строчки:
d:DesignWidth="640" d:DesignHeight="480"
Title="Page1 Page">
Изменим эти строчки так (равносильно изменению свойств, как уже было сказано):
d:DesignWidth="300" d:DesignHeight="300"
Title="Знакомство с Silverlight (C#) :: Основы анимации">
Теперь «запихнём» новую страницу в TabControl следующим образом. Откроем MainPage.xaml в конструкторе, найдём код добавления элемента TabControl и между тэгами добавим следующий XAML-код:
<lwp17:Page_BasicAnimation></lwp17:Page_BasicAnimation>
Напоминаем, слово lwp17 это доступ к пространству имён приложения (WPF-проекта) определённый в шапке страницы MainPage.xaml:
xmlns:lwp17="clr-namespace:LWP17Silverlight"
Откроем XAML-код страницы Page_BasicAnimation.xaml, найдём:
<Grid x:Name="LayoutRoot">
...
</Grid>
За место троеточия вставим:
<Rectangle x:Name="rectangle1" Fill="Turquoise"
Canvas.Top="100" Canvas.Left="100"
Width="100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation RepeatBehavior="3x"
Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height"
To="200" Duration="0:0:5"
AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Откомпилируем и увидим как ровный квадрат превращается в следующее:
Теперь немного теории:
BeginStoryboard («Начать раскадровку») — это действие триггера, содержащее объект Storyboard («Раскадровка»). Объекты раскадровки содержат определения анимации. При определении анимации эти объекты просто внедряются внутрь определения EventTrigger:
<Rectangle x:Name="rect" Fill="Red"
Canvas.Top="100" Canvas.Left="100"
Width="100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Теперь, когда инфраструктура для анимации установлена, можно указать, какую анимацию следует выполнить. На самом базовом уровне, анимация определяет изменение свойства с течением времени. Можно анимировать три различных типа свойств. Каждый из этих типов свойств анимируется из значения, указанного в атрибуте From («От») (или, если оно не установлено, из его текущего значения), к значению, указанному в атрибуте To («К»), либо к значению, указанному в атрибуте By («По»).
Двойные типы анимируются с помощью DoubleAnimation или DoubleAnimationUsingKeyFrames. Этот метод используется для анимации свойств, содержащих двойное значение — например, измерений, вроде Canvas.Left или визуальных атрибутов, вроде Opacity.
Типы точек анимируются с помощью PointAnimation или типа PointAnimationUsingKeyFrames. Этот конкретный метод используется для анимации свойств, содержащих значение точки, таких, как сегментов строк или кривых, определенных с использованием точек.
Типы цветов анимируются с помощью ColorAnimation или типа ColorAnimationUsingKeyFrames. Этот метод используется для анимации свойств, содержащих значение цвета — фона или штриха элемента, например.
Чтобы определить, к какому объекту следует применить анимацию, на этих типах анимации используется свойство Storyboard.TargetName и ему необходимо передать имя такого объекта, устанавливаемое на объекте с помощью свойства x:Name. Вдобавок, свойство, которое будет анимировано, указывается с помощью Storyboard.TargetProperty. Учтите, что при указании сложного или присоединенного свойства (такого как Canvas.Left), его следует поместить в скобки. Так, для примера, чтобы нацелить двойную анимацию на Height прямоугольника, именуемого rectangle1, XAML должен выглядеть следующим образом:
<DoubleAnimation Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height" />
Чтобы определить, сколько времени займёт переход затрагиваемых свойств от одного значения к другому, используется свойство Duration («Продолжительность»). Отметьте, что оно определено в формате чч:мм:сс, где пятисекундная продолжительность анимации указывается как 00:00:05, сокращенно 0:0:5.
<DoubleAnimation Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height" Duration="0:0:5" />
Если нежелательно, чтобы анимация началась немедленно, можно вставить задержку, используя свойство BeginTime и тот же синтаксис:
<DoubleAnimation Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height" BeginTime="0:0:5" />
Можно также скорректировать поведение анимации, умножив продолжительность на коэффициент скорости. Это проделывается с помощью свойства SpeedRatio. Например, в предыдущем случае продолжительность была установлена на 5 секунд. Можно изменить коэффициент скорости, заставив анимацию длиться 10 секунд, установив SpeedRatio на 2, или, как вариант, можно ускорить анимацию до 1 секунды, установив SpeedRatio на 0.2.
<DoubleAnimation Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height" SpeedRatio="2" Duration="0:0:5" />
Анимация Silverlight предоставляет средство для отмены изменений, внесённых как часть анимации. Например, если двойное значение переносится от 0 к 500 за определенный промежуток времени, AutoReverse заставит анимацию перейти от 500 обратно к нулю.
Если анимация установлена на работу в течении 5 секунд, как показано выше и AutoReverse установлен на true, то полная анимация займёт 10 секунд.
<DoubleAnimation Storyboard.TargetName="rectangle1"
Storyboard.TargetProperty="Height" SpeedRatio="2" Duration="0:0:5" AutoReverse="True" />
Когда работа анимации завершена, можно применить ряд параметров, чтобы заставить её вести себя нужным образом. Они указываются с помощью свойства RepeatBehavior. Это свойство может принимать три различных типа значений:
Время, определённое в секундах. Временная шкала подождет это время и затем начнёт анимацию снова.
Установка RepeatBehavior на Forever («Постоянно») для постоянного повторения.
Определенное число повторений, установленное путем указанием числа, за которым следует x. Например, если анимация должна произойти трижды, указывается значение 3х.
Анимация значения с помощью DoubleAnimation:
Объект DoubleAnimation позволяет указать, как будет меняться двойное значение на указанной временной шкале. Анимация вычисляется как линейная интерполяция между значениями свойств с течением времени.
При анимации двойного значения, значение в начале анимации указывается с помощью значения From и затем изменяется либо на значение To, являющееся абсолютной точкой назначения, либо на значение By, являющееся относительной точкой назначения. Например, если свойство Canvas.Left элемента перемещается от 100 (рядом с левой стороной экрана) к 500, можно установить From на 100 и To на 500, либо By на 400. Если установить оба, свойство To будет иметь больший приоритет, а свойство By игнорируется. Также, если прямоугольник уже размещён в желаемой позиции From, указывать свойство From не нужно.
Анимация цвета с помощью ColorAnimation:
ColorAnimation работает как DoubleAnimation. Оно используется для определения того, как значение цвета элемента будет меняться со временем. Анимация, вычисляется как линейная интерполяция между значениями свойств цвета с течением указанного времени.
При анимации цвета, его значение в начале анимации указывается с использованием свойства From. Если не указать его, то используется текущий цвет. Желательный конечный цвет указывается с использованием атрибута To. Можно также указать атрибут By, который предоставит конечный цвет, являющийся продуктом добавления значений цвета From (или начального цвета) к цвету By.
При анимации свойства, основанного на цвете, содержимое свойства не анимируется напрямую, поскольку содержимым свойства обычно является кисть, а не цвет. Так что если необходимо анимировать цвет заливки прямоугольника, в качестве цели не следует использовать свойство Fill («Заливка»). Вместо этого, следует указать, что собираетесь анимировать свойство Color («Цвет») используемой для выполнения заливки SolidBrush.
Пример анимации цвета прямоугольника и изменения его с чёрного на белый в течении пяти секунд (затем возвращение и вечное повторение), с помощью анимации света. Как можно заметить в коде ниже, этот фрагмент XAML указывает свойство Color, относящееся к заливающей фигуру SolidColorBrush, как свое целевое свойство. Добавим этот кусок кода на страницу Page_BasicAnimation.xaml после предыдущего фрагмента, закрывающего тэга прямоугольника:
<Rectangle x:Name="rectangle2"
Width="100" Height="100"
Fill="Black"
HorizontalAlignment="Left" VerticalAlignment="Top">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="rectangle2"
Storyboard.TargetProperty=
"(Shape.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Анимация точки с помощью PointAnimation:
Чтобы изменять значение, определённое как точка, с течением времени, используется тип PointAnimation. Анимация вычисляется как линейная интерполяция между значениями свойств цвета с течением указанного времени.
Подобно анимации двойных значений и значений цвета, значение в начале анимации указывается с помощью значения From, а конечное значение указывается либо как относительное направление (с помощью By), либо как абсолютная точка (с помощью To). Следующий код показывает пример того, как можно анимировать конечную точку кривой Безье. В данном случае, кривая Безье определяется со начальной точкой в (100,100), конечной точкой в (300,100) и контрольной точкой в (200,0). Анимация устанавливается на запуск после загрузки пути и она анимирует конечную точку кривой (Point2) от (300,100) до (300,200) на протяжении пяти секунд. Код добавляем после закрывающего тэга предыдущего фрагмента (прямоугольника):
<Path Stroke="Black">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="100,100">
<QuadraticBezierSegment x:Name="seg"
Point1="200,0" Point2="300,100" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<PointAnimation Storyboard.TargetName="seg"
Storyboard.TargetProperty="Point2"
From="300,100" To="300,200"
Duration="0:0:5" AutoReverse="True"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
Использование опорных кадров:
Все три типа анимации, о которых только что было рассказано, ColorAnimation, DoubleAnimation и PointAnimation работают путём изменения определённого свойства с течением времени, используя линейную интерполяцию. Например, при переводе двойного значения от 100 к 500 в течение пяти секунд, оно будет изменяться на 80 каждую секунду.
В каждом из этих трёх типов анимации данный перенос может быть определён через набор «вех», именуемых опорными кадрами. Чтобы изменить линейное поведение анимации от начального свойства к конечному свойству, следует просто вставить один или несколько опорных кадров. Затем определяется желаемый стиль анимации между этими различными точками.
Опорные кадры определяются с помощью «опорных моментов». Это моменты, указываемые относительно момента начала анимации; они также указывают время окончания опорного кадра. Так что если, для примера, необходима девятисекундная анимация с тремя равномерно распределёнными опорными моментами, можно указать окончание первого опорного момента в 0:0:3, второго в 0:0:6 и третьего в 0:0:9. Длина опорного момента не указывается: вместо этого указывается конечное время для каждого опорного кадра.
В качестве ещё одного примера, представим себе двойную анимацию, которая должна охватывать половину диапазона от 100 до 500. Анимация должна двигаться очень быстро в первой половине и очень медленно во второй. В целом, она будет требовать шести секунд переноса. Поскольку 350 – это середина между 100 и 500, опорный кадр следует определить как начинающийся в точке 350. Ему следует указать продолжаться одну секунду между начальной точкой и средней точкой (опорное время 0:0:1) и затем установить продолжительность опорного времени между средней точкой и конечной точкой в пять секунд, используя второе опорное время как 0:0:6. Теперь элемент установлен так, чтобы пролететь по экрану к средней точке и медленно ползти дальше.
В предыдущих примерах, оба сегмента анимации используют линейную интерполяцию. Для обеспечения большей гибкости, предоставлены два других типа опорных кадров: дискретный опорный кадр, который мгновенно перебрасывает значение между двумя значениями и сплайновый опорный кадр, который перемещает значение между начальной и конечной точками, используя квадратическую кривую для определения интерполяции.
Для указания опорных кадров на анимации используется постфикс UsingKeyFrames. То есть, для указания двойных анимаций и использования опорных кадров, следует использовать DoubleAnimationUsingKeyFrame, на котором указывается цель и свойство (тем же образом, что при использовании DoubleAnimation). DoubleAnimationUsingKeyFrames содержит определения опорных кадров. И то же самое относится к PointAnimationUsingKeyFrames или ColorAnimationUsingKeyFrames.
Использование линейных опорных кадров:
По умолчанию, методом анимации между двумя значениями свойств является линейная интерполяция, при которой протяженность равномерно накладывается на время. Можно также определить линейные шаги между кадрами, используя тип LinearKeyFrame, в котором линейная интерполяция также используется, но используется между опорными кадрами, что позволяет получить эффект ускорения/замедления. Добавляем следующий код на страницу, результатом, изменение ширины вначале первой секунды будет быстрым, затем в течении девяти секунд очень медленным:
<Rectangle Fill="#FFFF0000" Stroke="#FF000000"
Width="40" Height="40" x:Name="rectangle3">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rectangle3"
Storyboard.TargetProperty="Width" AutoReverse="True" RepeatBehavior="5x" >
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="100" />
<LinearDoubleKeyFrame KeyTime="0:0:9" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Использование дискретных опорных кадров:
Если необходимо изменить значение свойства, не используя линейную интерполяцию, то можно использовать дискретный опорный кадр. Это заставляет объект перескочить к значению на момент указанного опорного кадра. Добавляем следующий код на страницу, результатом будет скачкообразное изменение размеров фиолетового прямоугольника в течении трёх секунд:
<Rectangle Fill="#FFFF00FF" Stroke="#FF0000FF"
HorizontalAlignment="Center" VerticalAlignment="Bottom"
Width="20" Height="20" x:Name="rectangle4">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="rectangle4"
Storyboard.TargetProperty="Width" AutoReverse="True" RepeatBehavior="5x">
<DiscreteDoubleKeyFrame KeyTime="0:0:1" Value="100" />
<DiscreteDoubleKeyFrame KeyTime="0:0:2" Value="200" />
<DiscreteDoubleKeyFrame KeyTime="0:0:3" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Использование опорных кадров сплайна:
Если необходимо изменить значение свойства, используя искривляющееся значение, обеспечивающее ускорение и замедление, то используется дискретный опорный кадр. Для этого сперва определяется квадратичная кривая Безье, а затем скорость свойства, при его перемещении от одного значения к другому, определяется параллельной проекцией этой кривой.
Это похоже на следующую ситуацию: солнце прямо над головой и вы только что ударили по футбольному мячу. Вы смотрите на тень мяча. По мере того, как он взлетает выше, движение тени кажется ускоряющимся. В высшей точке полёта мяча, можно увидеть, что движение тени замедлилось. Когда мяч начинает падать, можно увидеть, что тень ускоряется снова, пока мяч не отобьют или он не коснётся земли.
Анимация, в этом случае — тень мяча, а сплайн — траектория полёта меча. Эта траектория, сплайн, определяется используя KeySpline. KeySpline определяет контрольные точки для квадратичной кривой Безье. Он нормализован так, что первой точкой кривой является 0, а второй 1. Для параболической дуги, по которой пролетел бы мяч, KeySpline будет содержать два нормализованных значения, разделенных запятыми.
Чтобы определить кривую, подобную полету мяча, можно определить сплайн, используя KeySpline, такой как 0.3, 0 0.6, 1. Это определит первую точку кривой как (0.3, 0), а вторую как (0.6, 1). Результатом этого будет быстрое ускорение анимации примерно до завершения одной трети полета мяча; затем она будет двигаться с единообразной скоростью, примерно до завершения второй трети; и наконец, будет уменьшаться в течение оставшейся части полета анимированного мяча, когда анимация имитирует падение мяча на землю. Код такой:
<Ellipse Fill="Aqua" Stroke="#FFFF4444" HorizontalAlignment="Right"
Width="20" Height="20" x:Name="ball1">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="ball1"
Storyboard.TargetProperty="Height" AutoReverse="True" RepeatBehavior="3x">
<SplineDoubleKeyFrame KeyTime="0:0:5"
KeySpline="0.3,0 0.6,1" Value="200" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
Теперь без долгих объяснений создаём «событийную» анимацию, о которой говорилось в начале данного пункта работы. Основу каждого последующего окна составит сетка, разделённая в соотношении 1:9 размеров окна. В верхней части сетки будет закреплена StackPanel с надписью, а в нижней будет создан объект Path с градиентом. Основу Path составит простой эллипс закрашенный этим градиентом. Для второго StackPanel будет инициализировано событие MouseLeftButtonDown для получения координат нажатия.
Создаём новую страницу с именем Page_BasicPointAnimation.xaml и XAML-кодом:
<navigation:Page x:Class="LWP17Silverlight.Page_BasicPointAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="300" d:DesignHeight="300"
Title="Знакомство с Silverlight (C#) :: Базовая точечная анимация с событиями">
<navigation:Page.Resources>
<Storyboard x:Name="MyStoryboard">
<PointAnimation x:Name="MyPointAnimation" Duration="0:0:2"
Storyboard.TargetProperty="Center"
Storyboard.TargetName="MyAnimatedEllipseGeometry">
</PointAnimation>
</Storyboard>
</navigation:Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="9*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="Щёлкните левой кнопкой мыши на любой позиции на сером фоне" TextAlignment="Center"></TextBlock>
</StackPanel>
<StackPanel MouseLeftButtonDown="StackPanel_MouseLeftButtonDown" x:Name="MyStackPanel" Background="Gray" Grid.Row="1">
<Path>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF1F7FB" Offset="0"/>
<GradientStop Color="#FF3794E4" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
<Path.Data>
<!-- Рисуем эллипс -->
<EllipseGeometry x:Name="MyAnimatedEllipseGeometry" Center="50,80" RadiusX="15" RadiusY="15" />
</Path.Data>
</Path>
</StackPanel>
</Grid>
</navigation:Page>
Код события MouseLeftButtonDown для файла Page_BasicPointAnimation.xaml.cs будет таким:
/// <summary>
/// Обработчик события изменяет свойство To объекта PointAnimation,
/// и начинает проигрывание анимации Storyboard
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var targetpoint = e.GetPosition(this.MyStackPanel);
this.MyPointAnimation.To = targetpoint;
this.MyStoryboard.Begin();
}
Код новой вкладки для TabControl:
<sdk:TabItem Header="Базовыя точечная анимации с событиями" Name="BasicPointAnimation" DataContext="{Binding}">
<lwp17:Page_BasicPointAnimation></lwp17:Page_BasicPointAnimation>
</sdk:TabItem>
Следующая вкладка выполняет похожую функцию, только «анимация» на этот раз нужна не только для эллипса, но и для линии, которая проводится из центра эллипса к точке, в которую эллипс должен быть перемещён. Для реализации помимо новой страницы также нам понадобится ещё одна дополнительная страница с классом.
Создаём новую страницу с именем Page_AimateDependencyProperty.xaml с XAML-кодом:
<navigation:Page x:Class="LWP17Silverlight.Page_AnimateDependencyProperty"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="clr-namespace:LWP17Silverlight;assembly=LWP17Silverlight"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="300" d:DesignHeight="300"
Title="Знакомство с Silverlight (C#) :: Анимация свойства зависимостей">
<navigation:Page.Resources>
<Storyboard x:Name="MyAnimationStoryboard">
<PointAnimation x:Name="MyAnimation"
Duration="0:0:2"
Storyboard.TargetProperty="EllipseCenter"
Storyboard.TargetName="MyAnimatedEllipseGeometry">
</PointAnimation>
</Storyboard>
</navigation:Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="9*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock Text="Щёлкните левой кнопкой мыши на любой позиции на чёрном фоне" TextAlignment="Center"></TextBlock>
</StackPanel>
<StackPanel x:Name="MyStackPanel" MouseLeftButtonDown="MyStackPanel_MouseLeftButtonDown" Background="Black" Grid.Row="1">
<Canvas>
<Line x:Name="MyLine" Fill="Red" Stroke="Red" Visibility="Collapsed" StrokeThickness="5" Canvas.ZIndex="1"></Line>
<c:MyEllipse x:Name="MyAnimatedEllipseGeometry" EllipseCenterChanged="MyAnimatedEllipseGeometry_EllipseCenterChanged"></c:MyEllipse>
</Canvas>
</StackPanel>
</Grid>
</navigation:Page>
Код новой вкладки для TabControl:
<sdk:TabItem Header="Анимация свойства зависимостей" Name="AnimateDependencyProperty" DataContext="{Binding}">
<lwp17:Page_AimateDependencyProperty></lwp17:Page_AimateDependencyProperty>
</sdk:TabItem>
Код файла Page_AnimateDependencyProperty.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace LWP17Silverlight
{
public partial class Page_AnimateDependencyProperty : Page
{
Point _currenttargetpoint;
public Page_AnimateDependencyProperty()
{
InitializeComponent();
}
// Выполняется, когда пользователь переходит на эту страницу.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void MyStackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_currenttargetpoint = e.GetPosition(this.MyStackPanel);
this.MyAnimation.To = _currenttargetpoint;
this.MyAnimationStoryboard.Begin();
}
/// <summary>
/// Сихнронизация конечной точки объекта MyLine c последней точкой
/// которую пользователь выбирает нажатием и текущей позицие объекта MyEllipse.
/// Анимация создаётся для MyLine
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MyAnimatedEllipseGeometry_EllipseCenterChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
this.MyLine.Visibility = Visibility.Visible;
this.MyLine.X1 = this.MyAnimatedEllipseGeometry.EllipseCenter.X;
this.MyLine.Y1 = this.MyAnimatedEllipseGeometry.EllipseCenter.Y;
this.MyLine.X2 = this._currenttargetpoint.X;
this.MyLine.Y2 = this._currenttargetpoint.Y;
}
}
}
Теперь создаём ещё одну страницу с именем MyEllipse.xaml и XAML-кодом:
<navigation:Page x:Class="LWP17Silverlight.MyEllipse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="clr-namespace:LWP17Silverlight;assembly=LWP17Silverlight"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="300" d:DesignHeight="300">
<Grid x:Name="LayoutRoot" Background="Transparent" IsHitTestVisible="False">
<Path>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF1F7FB" Offset="0"/>
<GradientStop Color="#FF3794E4" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
<Path.Data>
<EllipseGeometry x:Name="MyAnimatedEllipseGeometry"
Center="50,50" RadiusX="15" RadiusY="15" />
</Path.Data>
</Path>
</Grid>
</navigation:Page>
Код файла MyEllipse.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace LWP17Silverlight
{
public delegate void EllipseCenterChangedEventHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e);
public partial class MyEllipse : Page
{
public static readonly DependencyProperty EllipseCenterProperty =
DependencyProperty.Register("EllipseCenter", typeof(Point), typeof(MyEllipse),
new PropertyMetadata(new PropertyChangedCallback((obj, e) => { MyHandler(obj, e); })));
EllipseCenterChangedEventHandler _myDelegate;
public event EllipseCenterChangedEventHandler EllipseCenterChanged
{
add
{
if (_myDelegate == null) _myDelegate = value;
else { Delegate.Combine(_myDelegate, value); }
}
remove { Delegate.Remove(_myDelegate, value); }
}
public Point EllipseCenter
{
get { return (Point)GetValue(EllipseCenterProperty); }
set { SetValue(EllipseCenterProperty, value); }
}
public MyEllipse()
{
InitializeComponent();
EllipseCenter = this.MyAnimatedEllipseGeometry.Center;
}
/// <summary>
/// Это метод обратного вызова, который вызывает метод OnEllipseCenterChanged
/// объекта MyEllipse, свойство EllipseCenter которого было изменено
/// </summary>
/// <param name="obj"></param>
/// <param name="e"></param>
static void MyHandler(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MyEllipse ellipse = obj as MyEllipse;
if (ellipse != null) { ellipse.OnEllipseCenterChanged(obj, e); }
}
/// <summary>
/// Этот метод вызывается методом свойства EllipseCenterProperty.
/// Это обновляет свойство Center объекта MyAnimatedEllipseGeometry интерфейса,
/// когда срабатывает событие EllipseCenterChanged
/// </summary>
/// <param name="obj"></param>
/// <param name="e"></param>
void OnEllipseCenterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MyEllipse ellipse = obj as MyEllipse;
if (ellipse != null) { ellipse.MyAnimatedEllipseGeometry.Center = ellipse.EllipseCenter; }
if (_myDelegate != null) _myDelegate(obj, e);
}
}
}
Применение специально функции EasingFunction, позволяющей «настроить» анимацию различными способами:
<DoubleAnimation>
<DoubleAnimation.EasingFunction>
Функции
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
Создаём последнюю страницу с именем Page_EasingFunction.xaml с XAML-кодом:
<navigation:Page x:Class="LWP17Silverlight.Page_EasingFunction"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="clr-namespace:LWP17Silverlight;assembly=LWP17Silverlight"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="300" d:DesignHeight="300"
Title="Знакомство с Silverlight (C#) :: Применение EasingFunction">
<navigation:Page.Resources>
<BackEase x:Name="BackEase" Amplitude="1" EasingMode="EaseIn"></BackEase>
<c:MyEase x:Name="MyEase"></c:MyEase>
<Storyboard x:Name="MyAnimationStoryboard">
<PointAnimation x:Name="MyAnimation"
Duration="0:0:2"
Storyboard.TargetProperty="Center"
Storyboard.TargetName="MyAnimatedEllipseGeometry"
EasingFunction="{StaticResource BackEase}">
</PointAnimation>
</Storyboard>
</navigation:Page.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="3*"></RowDefinition>
<RowDefinition Height="7*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<RadioButton GroupName="g1" Content="Применяем BackEase" IsChecked="true" x:Name="BackEaseRadioButton" Click="BackEaseRadioButton_Click"></RadioButton>
<RadioButton GroupName="g1" Content="Применяем MyEase" IsChecked="false" x:Name="MyEaseRadioButton" Click="MyEaseRadioButton_Click"></RadioButton>
<TextBlock Text="Щёлкните левой кнопкой мыши на любой позиции на розовом фоне" TextAlignment="Center"></TextBlock>
</StackPanel>
<StackPanel MouseLeftButtonDown="MyStackPanel_MouseLeftButtonDown" x:Name="MyStackPanel" Background="Pink" Grid.Row="1">
<Path>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF1F7FB" Offset="0"/>
<GradientStop Color="#FF3794E4" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
<Path.Data>
<EllipseGeometry x:Name="MyAnimatedEllipseGeometry"
Center="50,50" RadiusX="15" RadiusY="15" />
</Path.Data>
</Path>
</StackPanel>
</Grid>
</navigation:Page>
Код события Click нажатия кнопки для файла Page_EasingFunction.xaml.cs, нажатия на одну из RadioButton, а также специальный класс MyEase будет таким (в одно файле):
private void MyStackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var targetpoint = e.GetPosition(this.MyStackPanel);
this.MyAnimation.To = targetpoint;
this.MyAnimationStoryboard.Begin();
}
private void MyEaseRadioButton_Click(object sender, RoutedEventArgs e)
{
this.MyAnimation.EasingFunction = this.Resources["MyEase"] as IEasingFunction;
}
private void BackEaseRadioButton_Click(object sender, RoutedEventArgs e)
{
this.MyAnimation.EasingFunction = this.Resources["BackEase"] as IEasingFunction;
}
}
/// <summary>
/// Класс MyEase
/// </summary>
public class MyEase : EasingFunctionBase
{
protected override double EaseInCore(double normalizedTime)
{
return normalizedTime / 5;
}
}
Код новой вкладки для TabControl:
<sdk:TabItem Header="Применение EasingFunction" Name="EasingFunction" DataContext="{Binding}">
<lwp17:Page_EasingFunction></lwp17:Page_EasingFunction>
</sdk:TabItem>
Следующая последняя вкладка будет запускать по нажатию кнопки анимацию «падения шарика на пол».
Создаём последнюю страницу с именем Page_UsingKeyFrames.xaml с XAML-кодом:
<navigation:Page x:Class="LWP17Silverlight.Page_UsingKeyFrames"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="300" d:DesignHeight="300"
Title="Знакомство с Silverlight (C#) :: Покадровая анимация">
<navigation:Page.Resources>
<Storyboard x:Name="MyAnimationStoryboard">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="path" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="-4" KeySpline="1,0,1,1"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="-5" KeySpline="0,0,0,1"/>
<SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="-4" KeySpline="1,0,1,1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="path" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="127" KeySpline="1,0,1,1"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="69" KeySpline="0,0,0,1"/>
<SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="127" KeySpline="1,0,1,1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</navigation:Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="9*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Button Content="Нажмите кнопку для начала анимации" Click="Button_Click"></Button>
</StackPanel>
<StackPanel x:Name="MyStackPanel" Background="WhiteSmoke" Grid.Row="1">
<Path x:Name="path" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFF1F7FB" Offset="0"/>
<GradientStop Color="#FF3794E4" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
<Path.Data>
<EllipseGeometry x:Name="MyAnimatedEllipseGeometry"
Center="50,50" RadiusX="15" RadiusY="15" />
</Path.Data>
</Path>
</StackPanel>
</Grid>
</navigation:Page>
Код события Click нажатия кнопки для файла Page_UsingKeyFrames.xaml.cs будет таким:
private void Button_Click(object sender, RoutedEventArgs e)
{
this.MyAnimationStoryboard.Begin();
}
Код новой вкладки для TabControl:
<sdk:TabItem Header="Покадровая анимация" Name="UsingKeyFrames" DataContext="{Binding}">
<lwp17:Page_UsingKeyFrames></lwp17:Page_UsingKeyFrames>
</sdk:TabItem>
Готово. Компилируем, проверяем работоспособность. Если требуется поменять заголовок страницы с приложением при запуске, открываем файлы LWP17SilverlightTestPage.aspx или LWP17SilverlightTestPage.html, и ищем так строку:
<title>LWP17Silverlight</title>