Search code examples
wpfvb.nettimerdispatchertimerdoubleanimation

How to count up by using Double Animation instead of by using Timer


The following code is counting up starting from 1 to forever by using Timer.

XAML codes:

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <Label x:Name="myLabel"/>
</Grid>
</Window>

vb.net codes:

Class MainWindow

Dim myDispatcherTimer As New Windows.Threading.DispatcherTimer With {.Interval = TimeSpan.FromSeconds(1)}

Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    AddHandler myDispatcherTimer.Tick, AddressOf Me.Hello
    myDispatcherTimer.Start()
End Sub

Public Sub Hello()
    Static myStatic As Integer = 0
    myStatic = myStatic + 1
    myLabel.Content = myStatic
End Sub

End Class

I want to count up by using Double Animation instead of by using Timer.

Is it possible?

Thanks in advance.


Solution

  • You may create an attached property of type double that sets the Content property of any ContentControl (e.g. a Label) to which it is applied.

    public static class Counter
    {
        public static readonly DependencyProperty CountProperty =
            DependencyProperty.RegisterAttached(
                "Count", typeof(double), typeof(Counter),
                new PropertyMetadata(0d, CountPropertyChanged));
    
        public static double GetCount(DependencyObject obj)
        {
            return (double)obj.GetValue(CountProperty);
        }
    
        public static void SetCount(DependencyObject obj, double value)
        {
            obj.SetValue(CountProperty, value);
        }
    
        private static void CountPropertyChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is ContentControl control)
            {
                control.Content = string.Format("{0:F0}", args.NewValue);
            }
        }
    }
    

    Then animate that property by an appropriate DoubleAnimation.

    <Label>
        <Label.Triggers>
            <EventTrigger RoutedEvent="Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation
                            Storyboard.TargetProperty="(local:Counter.Count)"
                            From="0" By="1" Duration="0:0:1"
                            IsCumulative="True" RepeatBehavior="Forever"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Label.Triggers>
    </Label>
    

    Since you apparently only want to show integer values, you may as well use an Int32Animation with an attached property of type int.

    public static class Counter
    {
        public static readonly DependencyProperty CountProperty =
            DependencyProperty.RegisterAttached(
                "Count", typeof(int), typeof(Counter),
                new PropertyMetadata(0, CountPropertyChanged));
    
        public static int GetCount(DependencyObject obj)
        {
            return (int)obj.GetValue(CountProperty);
        }
    
        public static void SetCount(DependencyObject obj, int value)
        {
            obj.SetValue(CountProperty, value);
        }
    
        private static void CountPropertyChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is ContentControl control)
            {
                control.Content = args.NewValue;
            }
        }
    }
    

    with

    <Storyboard>
        <Int32Animation
            Storyboard.TargetProperty="(local:Counter.Count)"
            From="0" By="1" Duration="0:0:1"
            IsCumulative="True" RepeatBehavior="Forever"/>
    </Storyboard>