internal void EvaluateAnimatedValue( PropertyMetadata metadata, ref EffectiveValueEntry entry) { DependencyObject d = (DependencyObject)_dependencyObject.Target; if (d == null) { return; } object value = entry.GetFlattenedEntry(RequestFlags.FullyResolved).Value; if (entry.IsDeferredReference) { DeferredReference dr = (DeferredReference)value; value = dr.GetValue(entry.BaseValueSourceInternal); // Set the baseValue back into the entry entry.SetAnimationBaseValue(value); } object animatedValue = GetCurrentPropertyValue(this, d, _dependencyProperty, metadata, value); if (!_dependencyProperty.IsValidValueInternal(animatedValue)) { // If the animation(s) applied to the property have calculated an // invalid value for the property then raise an exception. throw new InvalidOperationException( SR.Get( SRID.Animation_CalculatedValueIsInvalidForProperty, _dependencyProperty.Name, null)); } entry.SetAnimatedValue(animatedValue, value); }
private void OnCurrentTimeInvalidated(object sender, EventArgs args) { object target = _dependencyObject.Target; if (target == null) { // If the target has been garbage collected, remove this handler // from the AnimationClock so that this collection can be // released also. DetachAnimationClock((AnimationClock)sender, _removeRequestedHandler); } else { // recompute animated value try { DependencyObject targetDO = ((DependencyObject)target); // fetch the existing entry EffectiveValueEntry oldEntry = targetDO.GetValueEntry( targetDO.LookupEntry(_dependencyProperty.GlobalIndex), _dependencyProperty, null, RequestFlags.RawEntry); EffectiveValueEntry newEntry; object value; // create a copy of that entry, removing animated & coerced values if (!oldEntry.HasModifiers) { // no modifiers; just use it, removing deferred references newEntry = oldEntry; value = newEntry.Value; if (newEntry.IsDeferredReference) { value = ((DeferredReference)value).GetValue(newEntry.BaseValueSourceInternal); newEntry.Value = value; } } else { // else entry has modifiers; preserve expression but throw away // coerced & animated values, since we'll be recomputing an animated value newEntry = new EffectiveValueEntry(); newEntry.BaseValueSourceInternal = oldEntry.BaseValueSourceInternal; newEntry.PropertyIndex = oldEntry.PropertyIndex; newEntry.HasExpressionMarker = oldEntry.HasExpressionMarker; value = oldEntry.ModifiedValue.BaseValue; if (oldEntry.IsDeferredReference) { DeferredReference dr = value as DeferredReference; if (dr != null) { value = dr.GetValue(newEntry.BaseValueSourceInternal); } } newEntry.Value = value; if (oldEntry.IsExpression) { value = oldEntry.ModifiedValue.ExpressionValue; if (oldEntry.IsDeferredReference) { DeferredReference dr = value as DeferredReference; if (dr != null) { value = dr.GetValue(newEntry.BaseValueSourceInternal); } } newEntry.SetExpressionValue(value, newEntry.Value); } } // compute the new value for the property PropertyMetadata metadata = _dependencyProperty.GetMetadata(targetDO.DependencyObjectType); object animatedValue = AnimationStorage.GetCurrentPropertyValue(this, targetDO, _dependencyProperty, metadata, value); if (_dependencyProperty.IsValidValueInternal(animatedValue)) { // update the new entry to contain the new animated value newEntry.SetAnimatedValue(animatedValue, value); // call UpdateEffectiveValue to put the new entry in targetDO's effective values table targetDO.UpdateEffectiveValue( targetDO.LookupEntry(_dependencyProperty.GlobalIndex), _dependencyProperty, metadata, oldEntry, ref newEntry, false /* coerceWithDeferredReference */, false /* coerceWithCurrentValue */, OperationType.Unknown); if (_hadValidationError) { if (TraceAnimation.IsEnabled) { TraceAnimation.TraceActivityItem( TraceAnimation.AnimateStorageValidationNoLongerFailing, this, animatedValue, target, _dependencyProperty); _hadValidationError = false; } } } else if (!_hadValidationError) { if (TraceAnimation.IsEnabled) { TraceAnimation.TraceActivityItem( TraceAnimation.AnimateStorageValidationFailed, this, animatedValue, target, _dependencyProperty); } _hadValidationError = true; } } catch (Exception e) { // Catch all exceptions thrown during the InvalidateProperty callstack // and wrap them in an AnimationException throw new AnimationException( (AnimationClock)sender, _dependencyProperty, (IAnimatable)target, SR.Get( SRID.Animation_Exception, _dependencyProperty.Name, target.GetType().FullName, ((AnimationClock)sender).Timeline.GetType().FullName), e); } } }