/// <summary>
        /// Handles a change to the TickTime property.
        /// </summary>
        /// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
        /// <param name="dependencyPropertyChangedEventArgs">Event data that that tracks changes to the effective value of this property.</param>
        static void OnTickTimePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            // IMPORTANT CONCEPT: in any virtualized panel, we need to accept that any given control can be recycled and re-realized at any time, even during an
            // animation which could last several seconds. To account for this in our design, we don't store the state of any animation.  When a new data context is
            // provided for this control, we'll use the start time from the View Model and the current time and calculate how much time is left in the animation. In
            // this way, when a PriceControl is realized, it will pick up how far into the animation cycle we are and provide animation only for as long as the
            // control is realized (or until the animation is complete).
            PriceControl priceControl = dependencyObject as PriceControl;
            Duration     elapsedTime  = new Duration(DateTime.Now.Subtract((DateTime)dependencyPropertyChangedEventArgs.NewValue));

            //  This will animate the background in the currently selected background color until the time since the last tick is equal to or greater than the
            //  PriceControl.TickDuration property.
            if (elapsedTime < priceControl.TickDuration)
            {
                // This is the amount of time remaining in the animation.
                Duration remainingDuration = priceControl.TickDuration - elapsedTime;

                // The most important part of this animation, to make it appear as if we've been keeping track of all the price changes in the entire virtual
                // space, is to calculate the current age of the tick and from that interpolate the current state of animation.
                Double proRata = remainingDuration.TimeSpan.TotalMilliseconds / priceControl.TickDuration.TimeSpan.TotalMilliseconds;
                Double from    = priceControl.TickOpacity * proRata;

                // We will only animate this control as long as it is realized or until the interpolated animation has completed.  Note that we take the time to
                // clean up after the animation is completed as there are likely to be many items that are animated and the lifetime of any one PriceControl is
                // indefinite.  Note that this is a relatively slow animation and there will likely be many of them, so we've chosen a framerate that will not
                // overly tax the CPU.
                DoubleAnimation opacityAnimation = new DoubleAnimation();
                opacityAnimation.Completed   += priceControl.OnAnimationCompleted;
                opacityAnimation.Duration     = remainingDuration;
                opacityAnimation.FillBehavior = FillBehavior.Stop;
                opacityAnimation.From         = from;
                Timeline.SetDesiredFrameRate(opacityAnimation, 4);
                priceControl.BeginAnimation(PriceControl.MaskOpacityProperty, opacityAnimation, HandoffBehavior.SnapshotAndReplace);
            }
        }
        /// <summary>
        /// Handles a change to the LastPrice property.
        /// </summary>
        /// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
        /// <param name="dependencyPropertyChangedEventArgs">Event data that that tracks changes to the effective value of this property.</param>
        static void OnLastPricePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            // This makes sure that the mask background color reflect the direction of the price change.
            PriceControl priceControl = dependencyObject as PriceControl;

            priceControl.MaskBackground = priceControl.LastPrice <priceControl.Price?priceControl.TickUpBackground :
                                                                  priceControl.LastPrice> priceControl.Price ? priceControl.TickDownBackground :
                                          null;
        }
        /// <summary>
        /// Handles a change to the Price property.
        /// </summary>
        /// <param name="dependencyObject">The DependencyObject on which the property has changed value.</param>
        /// <param name="dependencyPropertyChangedEventArgs">Event data that that tracks changes to the effective value of this property.</param>
        static void OnPricePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            // This will make sure that the background mask reflects the proper price change
            PriceControl priceControl = dependencyObject as PriceControl;

            priceControl.MaskBackground = priceControl.LastPrice <priceControl.Price?priceControl.TickUpBackground :
                                                                  priceControl.LastPrice> priceControl.Price ? priceControl.TickDownBackground :
                                          null;
            priceControl.Content = priceControl.Price;
        }