#c_sharp #wpf #анимация #property
Есть класс, представляющий игрока (привожу упрощенный вариант): class Player : INotifyPropertyChanged { public string Name { get; } int rank; public int Rank { get { return rank; } set { rank = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Rank")); } } public event PropertyChangedEventHandler PropertyChanged; public Player(string name) { Name = name; } } Коллекция этих Players отображается, ну скажем, в ItemsControl:Внешние силы меняют рейтинг игрока (не часто, не чаще 1 раза в несколько секунд). Можно ли сделать средствами анимации WPF (не принципиально) так, чтобы при изменении рейтинга число в TextBox'е менялось плавно от текущего значения до нового, ну скажем, за 0.2 секунды? Я могу, конечно, в сеттере запускать таймер, но это решение мне не нравится.
Ответы
Ответ 1
Такой фичи из коробки нету, но её можно легко смастерить самостоятельно. Например, давайте заведём для этого attached property. public static class AnimatableDoubleHelper { // Это attached property OriginalProperty. К нему мы будем привязывать свойство из VM, // и получать нотификацию об его изменении public static double GetOriginalProperty(DependencyObject obj) => (double)obj.GetValue(OriginalPropertyProperty); public static void SetOriginalProperty(DependencyObject obj, double value) => obj.SetValue(OriginalPropertyProperty, value); public static readonly DependencyProperty OriginalPropertyProperty = DependencyProperty.RegisterAttached( "OriginalProperty", typeof(double), typeof(AnimatableDoubleHelper), new PropertyMetadata(OnOriginalUpdated)); // это "производное" attached property, которое будет // анимированно "догонять" OriginalProperty public static double GetAnimatedProperty(DependencyObject obj) => (double)obj.GetValue(AnimatedPropertyProperty); public static void SetAnimatedProperty(DependencyObject obj, double value) => obj.SetValue(AnimatedPropertyProperty, value); public static readonly DependencyProperty AnimatedPropertyProperty = DependencyProperty.RegisterAttached( "AnimatedProperty", typeof(double), typeof(AnimatableDoubleHelper)); // это вызывается когда значение OriginalProperty меняется static void OnOriginalUpdated(DependencyObject o, DependencyPropertyChangedEventArgs e) { double newValue = (double)e.NewValue; // находим элемент, на котором меняется свойство FrameworkElement self = (FrameworkElement)o; DoubleAnimation animation = // создаём анимацию... new DoubleAnimation(newValue, new Duration(TimeSpan.FromSeconds(0.3))); // и запускаем её на AnimatedProperty self.BeginAnimation(AnimatedPropertyProperty, animation); } } Как этим пользоваться? Очень просто. Пусть у нас был такой код:Заменяем его на следующую конструкцию: Получается вот что:
Комментариев нет:
Отправить комментарий