internal void SetCoersionBaseValue(object coersionBaseValue) { if (!HasModifiers) { Value = coersionBaseValue; } else { ModifiedValue modifiedValue = ModifiedValue; if (IsAnimated) { modifiedValue.AnimatedValue = coersionBaseValue; } else if (IsExpression) { modifiedValue.ExpressionValue = coersionBaseValue; } else { modifiedValue.BaseValue = coersionBaseValue; } //the modified value may be a deferred reference so recompute this flag. ComputeIsDeferred(); } }
internal void SetExpressionValue(object value, object baseValue) { Debug.Assert(value != DependencyProperty.UnsetValue); ModifiedValue modifiedValue = EnsureModifiedValue(); modifiedValue.ExpressionValue = value; IsExpression = true; IsDeferredReference = value is DeferredReference; Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference)); Debug.Assert(IsDeferredReference == (value is DeferredReference)); }
internal void ResetCoercedValue() { if (IsCoerced) { ModifiedValue modifiedValue = ModifiedValue; modifiedValue.CoercedValue = null; IsCoerced = false; if (!HasModifiers) { Value = modifiedValue.BaseValue; } else { ComputeIsDeferred(); } } }
internal void ResetAnimatedValue() { if (IsAnimated) { ModifiedValue modifiedValue = ModifiedValue; modifiedValue.AnimatedValue = null; IsAnimated = false; if (!HasModifiers) { Value = modifiedValue.BaseValue; } else { // The setter takes care of the IsDeferred flag no need to compute it twice. ComputeIsDeferred(); } } }
internal void SetAnimatedValue(object value, object baseValue) { Debug.Assert((value != DependencyProperty.UnsetValue) && !(value is DeferredReference)); ModifiedValue modifiedValue = EnsureModifiedValue(); modifiedValue.AnimatedValue = value; IsAnimated = true; // Animated values should never be deferred IsDeferredReference = false; Debug.Assert(!(modifiedValue.AnimatedValue is DeferredReference)); Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue) || Object.Equals(modifiedValue.ExpressionValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference) && !(modifiedValue.BaseValue is DeferredReference) && !(modifiedValue.ExpressionValue is DeferredReference)); }
private ModifiedValue EnsureModifiedValue(bool useWeakReferenceForBaseValue = false) { ModifiedValue modifiedValue = null; if (_value == null) { _value = modifiedValue = new ModifiedValue(); } else { modifiedValue = _value as ModifiedValue; if (modifiedValue == null) { modifiedValue = new ModifiedValue(); modifiedValue.SetBaseValue(_value, useWeakReferenceForBaseValue); _value = modifiedValue; } } return(modifiedValue); }
// add an expression marker back as the base value for an expression value internal void RestoreExpressionMarker() { if (HasModifiers) { ModifiedValue entry = ModifiedValue; entry.ExpressionValue = entry.BaseValue; entry.BaseValue = DependencyObject.ExpressionInAlternativeStore; _source |= FullValueSource.IsExpression | FullValueSource.HasExpressionMarker; //recompute the isDeferredReference flag as it may have changed ComputeIsDeferred(); } else { object value = Value; Value = DependencyObject.ExpressionInAlternativeStore; SetExpressionValue(value, DependencyObject.ExpressionInAlternativeStore); _source |= FullValueSource.HasExpressionMarker; } }
internal void SetCoercedValue(object value, object baseValue, bool skipBaseValueChecks, bool coerceWithCurrentValue) { Debug.Assert(value != DependencyProperty.UnsetValue && !((value is DeferredReference) && !coerceWithCurrentValue)); // if this is already a CoercedWithControlValue entry, we are applying a // second coercion (e.g. from the CoerceValueCallback). The baseValue // passed in is the result of the control-value coercion, but for the // purposes of this method we should use the original base value instead. if (IsCoercedWithCurrentValue) { baseValue = ModifiedValue.BaseValue; } ModifiedValue modifiedValue = EnsureModifiedValue(coerceWithCurrentValue); modifiedValue.CoercedValue = value; IsCoerced = true; IsCoercedWithCurrentValue = coerceWithCurrentValue; // The only CoercedValues that can be deferred are Control values. if (coerceWithCurrentValue) { IsDeferredReference = (value is DeferredReference); } else { IsDeferredReference = false; } Debug.Assert(skipBaseValueChecks || Object.Equals(modifiedValue.BaseValue, baseValue) || Object.Equals(modifiedValue.ExpressionValue, baseValue) || Object.Equals(modifiedValue.AnimatedValue, baseValue)); Debug.Assert(!(baseValue is DeferredReference) && !(modifiedValue.BaseValue is DeferredReference) && !(modifiedValue.ExpressionValue is DeferredReference) && !(modifiedValue.AnimatedValue is DeferredReference)); }
internal EffectiveValueEntry GetFlattenedEntry(RequestFlags requests) { if ((_source & (FullValueSource.ModifiersMask | FullValueSource.HasExpressionMarker)) == 0) { // If the property does not have any modifiers // then just return the base value. return(this); } if (!HasModifiers) { Debug.Assert(HasExpressionMarker); // This is the case when some one stuck an expression into // an alternate store such as a style or a template but the // new value for the expression has not been evaluated yet. // In the intermediate we need to return the default value // for the property. This problem was manifested in DRTDocumentViewer. EffectiveValueEntry unsetEntry = new EffectiveValueEntry(); unsetEntry.BaseValueSourceInternal = BaseValueSourceInternal; unsetEntry.PropertyIndex = PropertyIndex; return(unsetEntry); } // else entry has modifiers EffectiveValueEntry entry = new EffectiveValueEntry(); entry.BaseValueSourceInternal = BaseValueSourceInternal; entry.PropertyIndex = PropertyIndex; entry.IsDeferredReference = IsDeferredReference; // If the property has a modifier return the modified value Debug.Assert(ModifiedValue != null); // outside of DO, we flatten modified value ModifiedValue modifiedValue = ModifiedValue; // Note that the modified values have an order of precedence // 1. Coerced Value (including Current value) // 2. Animated Value // 3. Expression Value // Also note that we support any arbitrary combinations of these // modifiers and will yet the precedence metioned above. if (IsCoerced) { if ((requests & RequestFlags.CoercionBaseValue) == 0) { entry.Value = modifiedValue.CoercedValue; } else { // This is the case when CoerceValue tries to query // the old base value for the property if (IsCoercedWithCurrentValue) { entry.Value = modifiedValue.CoercedValue; } else if (IsAnimated && ((requests & RequestFlags.AnimationBaseValue) == 0)) { entry.Value = modifiedValue.AnimatedValue; } else if (IsExpression) { entry.Value = modifiedValue.ExpressionValue; } else { entry.Value = modifiedValue.BaseValue; } } } else if (IsAnimated) { if ((requests & RequestFlags.AnimationBaseValue) == 0) { entry.Value = modifiedValue.AnimatedValue; } else { // This is the case when [UI/Content]Element are // requesting the base value of an animation. if (IsExpression) { entry.Value = modifiedValue.ExpressionValue; } else { entry.Value = modifiedValue.BaseValue; } } } else { Debug.Assert(IsExpression == true); object expressionValue = modifiedValue.ExpressionValue; entry.Value = expressionValue; } Debug.Assert(entry.IsDeferredReference == (entry.Value is DeferredReference), "Value and DeferredReference flag should be in [....]; hitting this may mean that it's time to divide the DeferredReference flag into a set of flags, one for each modifier"); return(entry); }
private ModifiedValue EnsureModifiedValue(bool useWeakReferenceForBaseValue=false) { ModifiedValue modifiedValue = null; if (_value == null) { _value = modifiedValue = new ModifiedValue(); } else { modifiedValue = _value as ModifiedValue; if (modifiedValue == null) { modifiedValue = new ModifiedValue(); modifiedValue.SetBaseValue(_value, useWeakReferenceForBaseValue); _value = modifiedValue; } } return modifiedValue; }
private ModifiedValue EnsureModifiedValue() { ModifiedValue modifiedValue = null; if (_value == null) { _value = modifiedValue = new ModifiedValue(); } else { modifiedValue = _value as ModifiedValue; if (modifiedValue == null) { modifiedValue = new ModifiedValue(); modifiedValue.BaseValue = _value; _value = modifiedValue; } } return modifiedValue; }