Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Анимация WPF при изменении свойства

#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); } } Как этим пользоваться? Очень просто. Пусть у нас был такой код: Заменяем его на следующую конструкцию: Получается вот что:

Комментариев нет:

Отправить комментарий