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); }
/// <summary> /// Check to see if there is a complex path that started with the /// given target object and property. If so, process the complex path /// information and return the results. /// </summary> internal static void GetComplexPathValue( DependencyObject targetObject, DependencyProperty targetProperty, ref EffectiveValueEntry entry, PropertyMetadata metadata) { CloneCacheEntry cacheEntry = GetComplexPathClone(targetObject, targetProperty); if (cacheEntry != null) { object baseValue = entry.Value; if (baseValue == DependencyProperty.UnsetValue) { // If the incoming baseValue is DependencyProperty.UnsetValue, that // means the current property value is the default value. Either // the cacheEntry.Clone was a clone of a default value (and should be // returned to the caller) or someone called ClearValue() (and // cacheEntry.Clone should be cleared accordingly). // To distinguish these cases we must check the cached source // against the default value. // // We don't have to handle the ClearValue case in this clause; // the comparison with the cached source to the base value // will fail in that case (since the cached source won't be UnsetValue) // and we'll clear out the cache. Debug.Assert(cacheEntry.Source != DependencyProperty.UnsetValue, "Storyboard complex path’s clone cache should never contain DependencyProperty.UnsetValue. Either something went wrong in Storyboard.ProcessComplexPath() or somebody else is messing with the Storyboard clone cache."); if (cacheEntry.Source == metadata.GetDefaultValue(targetObject, targetProperty)) { // The cacheEntry.Clone is the clone of the default value. In normal // non-Storyboard code paths, BaseValueSourceInternal is Unknown for default // values at this time, so we need to switch it over explicitly. // // And to prevent DependencyObject.UpdateEffectiveValue from misconstruing this // as an unaltered default value (which would result in UEV thinking no change // in value occurred and discarding this new value), we will go ahead and set the // animated value modifier on this value entry. (jeffbog: B#1616678 5/19/2006) // // In all other cases, valueSource should have the correct // valueSource corresponding to the object we cloned from, // so we don't need to do anything. entry.BaseValueSourceInternal = BaseValueSourceInternal.Default; entry.SetAnimatedValue(cacheEntry.Clone, DependencyProperty.UnsetValue); return; } } // If the incoming baseValue is a deferred object, we need to get the // real value to make a valid comparison against the cache entry source. DeferredReference deferredBaseValue = baseValue as DeferredReference; if (deferredBaseValue != null) { baseValue = deferredBaseValue.GetValue(entry.BaseValueSourceInternal); entry.Value = baseValue; } // If the incoming baseValue is different from the original source object that // we cloned and cached then we need to invalidate this cache. Otherwise we use // the value in the cache as is. if (cacheEntry.Source == baseValue) { CloneEffectiveValue(ref entry, cacheEntry); return; } else { // Setting to DependencyProperty.UnsetValue is how FrugalMap does delete. SetComplexPathClone( targetObject, targetProperty, DependencyProperty.UnsetValue, DependencyProperty.UnsetValue); } } }