There is a class representing the player (I give a simplified version):

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; } } 

A collection of these Players is displayed, let's say, in ItemsControl:

 <ItemsControl Name="icPlayers"> <ItemsControl.ItemTemplate> <DataTemplate> <Border Margin="0,2.5" Padding="5" BorderThickness="1" BorderBrush="DarkBlue"> <StackPanel> <TextBlock Text="{Binding Path=Name, Mode=OneTime}" FontWeight="Bold"/> <StackPanel Orientation="Horizontal"> <TextBlock Text="Рейтинг:" Margin="0,0,3,0"/> <TextBlock Text="{Binding Path=Rank, Mode=OneWay}" FontWeight="DemiBold"/> </StackPanel> </StackPanel> </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 

External forces change the player's rating (not often, not more than 1 time in a few seconds).

Is it possible to make WPF animations (not fundamentally) so that when the rating changes, the number in TextBox changes smoothly from the current value to the new, say, in 0.2 seconds?

I can, of course, start a timer in the setter, but I don’t like this solution.

    1 answer 1

    There is no such feature from the box, but you can easily make it yourself. For example, let's get attached property for this.

     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); } } 

    How to use it? Very simple. Suppose we had this code:

     <TextBlock Text="{Binding Rank, StringFormat=0}"/> 

    We replace it with the following construction:

     <TextBlock local:AnimatableDoubleHelper.OriginalProperty="{Binding Rank}" Text="{Binding (local:AnimatableDoubleHelper.AnimatedProperty), RelativeSource={RelativeSource Self}, StringFormat=0}"/> 

    It turns out that:

    everyone loves anima!

    • VladD, and than you do such gif-ki? (if not a secret, of course). - BlackWitcher
    • what you need, thanks! - Andrey NOP
    • 3
      @BlackWitcher: I scored on gif screencast windows free in Google, and the first results were superuser.com , and he brought me to LICEcap. The same functionality of the program is still the sea. - VladD
    • @ Andrei: Please! Glad that helped. - VladD
    • one
      @Andrey : here changes: pastebin.com/q9fHdvRq - VladD