Язык программирования C#9 и платформа .NET5
Следует уяснить, что классы
могут подключаться к любому свойству зависимости заданного объекта, которое имеет соответствующий тип. Как объяснялось в главе 25, свойства зависимости являются специальной формой свойств, которую требуют многие службы WPF, включая анимацию, привязку данных и стили.AnimationПо соглашению свойство зависимости определяется как статическое, доступное только для чтения поле класса, имя которого образуется добавлением слова
к нормальному имени свойства. Например, для обращения к свойству зависимости для свойстваPropertyклассаHeightв коде будет использоватьсяButton.Button.HeightPropertyСвойства То, From и By
Во всех классах
определены следующие ключевые свойства, которые управляют начальным и конечным значениями, применяемыми для выполнения анимации:Animation•
— представляет конечное значение анимации;То•
— представляет начальное значение анимации;From•
— представляет общую величину, на которую анимация изменяет начальное значение.ByНесмотря на тот факт, что все классы поддерживают свойства
,ТоиFrom, они не получают их через виртуальные члены базового класса. Причина в том, что лежащие в основе типы, упакованные внутри указанных свойств, варьируются в широких пределах (целые числа, цвета, объектыByи т.д.), и представление всех возможностей через единственный базовый класс привело бы к очень сложным кодовым конструкциям.ThicknessВ связи со сказанным может возникнуть вопрос: почему не использовались обобщения .NET для определения единственного обобщенного класса анимации с одиночным параметром типа (скажем,
)? Опять-таки, поскольку существует огромное количество типов данных (цвета, векторы, целые числа, строки и т.д.), применяемых для анимации свойств зависимости, решение оказалось бы не настолько ясным, как можно было бы ожидать (не говоря уже о том, что XAML обеспечивает лишь ограниченную поддержку обобщенных типов).Animate<T>Роль базового класса Timeline
Хотя для определения виртуальных свойств
,ТоиFromне использовался единственный базовый класс, классыByвсе же разделяют общий базовый класс —Animation. Данный тип предлагает набор дополнительных свойств, которые управляют темпом продвижения анимации (табл. 27.1).System.Windows.Media.Animation.TimelineРеализация анимации в коде C#
Вы построите окно, содержащее элемент
, который обладает довольно странным поведением: когда на него наводится курсор мыши, он вращается вокруг своего левого верхнего угла. Начните с создания в Visual Studio нового проекта приложения WPF по имениButton. Модифицируйте начальную разметку, как показано ниже (обратите внимание на обработку событияSpinningButtonAnimationAppкнопки):MouseEnter<Button x:Name="btnSpinner" Height="50" Width="100" Content="I Spin!"MouseEnter="btnSpinner_MouseEnter" Click="btnSpinner_OnClick"/>В файле отделенного кода импортируйте пространство имен
и добавьте в файл C# следующий код:System.Windows.Media.Animationprivate bool _isSpinning=false;private void btnSpinner_MouseEnter(object sender, MouseEventArgs e){if (!_isSpinning){_isSpinning=true;<b> // Создать объект DoubleAnimation и зарегистрировать</b><b> // его с событием Completed.</b>var dblAnim=new DoubleAnimation();dblAnim.Completed +=(o, s)=> { _isSpinning=false; };<b> // Установить начальное и конечное значения.</b>dblAnim.From=0;dblAnim.To=360;<b> // Создать объект RotateTransform и присвоить</b><b> // его свойству RenderTransform кнопки.</b>var rt=new RotateTransform();btnSpinner.RenderTransform=rt;<b> // Выполнить анимацию объекта RotateTransform.</b>rt.BeginAnimation(RotateTransform.AngleProperty, dblAnim);}}private void btnSpinner_OnClick(object sender, RoutedEventArgs e){}Первая крупная задача метода
связана с конфигурированием объектаbtnSpinner_MouseEnter(), который будет начинать со значенияDoubleAnimationи заканчивать значением0. Обратите внимание, что для этого объекта также обрабатывается событие360, где переключается булевская переменная уровня класса, которая применяется для того, чтобы выполняющаяся анимация не была сброшена в начало.CompletedЗатем создается объект
, который подключается к свойствуRotateTransformэлемента управленияRenderTransform(Button). Наконец, объектbtnSpinnerинформируется о начале анимации его свойстваRenderTransformс использованием объектаAngle. Реализация анимации в коде обычно осуществляется путем вызова методаDoubleAnimationи передачи ему лежащего в основе свойства зависимости, к которому необходимо применить анимацию (вспомните, что по соглашению оно определено как статическое поле класса), и связанного объекта анимации.BeginAnimation()
