EffectiveValueEntry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Base / System / Windows / EffectiveValueEntry.cs / 1 / EffectiveValueEntry.cs

                            /****************************************************************************\ 
*
* File: EffectiveValueEntry.cs
*
*  This file describes an entry in the EffectiveValues list held by a 
*  DependencyObject.
* 
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 

using MS.Internal.WindowsBase;  // FriendAccessAllowed
using System.Collections;       // IDictionary
using System.Diagnostics;       // Debug.Assert 

namespace System.Windows 
{ 
    [FriendAccessAllowed] // Built into Base, also used by Core & Framework.
    internal struct EffectiveValueEntry 
    {
        #region InternalMethods

        internal static EffectiveValueEntry CreateDefaultValueEntry(DependencyProperty dp, object value) 
        {
            EffectiveValueEntry entry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Default); 
            entry.Value = value; 
            return entry;
        } 

        internal EffectiveValueEntry(DependencyProperty dp)
        {
            _propertyIndex = (short) dp.GlobalIndex; 
            _value = null;
            _source = (FullValueSource) BaseValueSourceInternal.Unknown; 
        } 

        internal EffectiveValueEntry(DependencyProperty dp, BaseValueSourceInternal valueSource) 
        {
            _propertyIndex = (short) dp.GlobalIndex;
            _value = DependencyProperty.UnsetValue;
            _source = (FullValueSource) valueSource; 
        }
 
        internal EffectiveValueEntry(DependencyProperty dp, FullValueSource fullValueSource) 
        {
            _propertyIndex = (short) dp.GlobalIndex; 
            _value = DependencyProperty.UnsetValue;
            _source = fullValueSource;
        }
 
        internal void SetExpressionValue(object value, object baseValue)
        { 
            Debug.Assert(value != DependencyProperty.UnsetValue); 

            ModifiedValue modifiedValue = EnsureModifiedValue(); 
            modifiedValue.ExpressionValue = value;
            IsExpression = true;

            Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue)); 
            Debug.Assert(!(baseValue is DeferredReference));
            Debug.Assert(IsDeferredReference == (value is DeferredReference)); 
        } 

        internal void SetAnimatedValue(object value, object baseValue) 
        {
            Debug.Assert((value != DependencyProperty.UnsetValue) &&
                         !(value is DeferredReference));
 
            ModifiedValue modifiedValue = EnsureModifiedValue();
            modifiedValue.AnimatedValue = value; 
            IsAnimated = true; 

            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)); 
        }
 
        internal void SetCoercedValue(object value, object baseValue, bool skipBaseValueChecks) 
        {
            Debug.Assert(value != DependencyProperty.UnsetValue && 
                         !(value is DeferredReference));

            ModifiedValue modifiedValue = EnsureModifiedValue();
            modifiedValue.CoercedValue = value; 
            IsCoerced = true;
 
            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 void ResetExpressionValue()
        { 
            if (IsExpression)
            {
                ModifiedValue modifiedValue = ModifiedValue;
                modifiedValue.ExpressionValue = null; 
                IsExpression = false;
 
                if (!HasModifiers) 
                {
                    Value = modifiedValue.BaseValue; 
                }
            }
        }
 
        internal void ResetAnimatedValue()
        { 
            if (IsAnimated) 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
                modifiedValue.AnimatedValue = null;
                IsAnimated = false;

                if (!HasModifiers) 
                {
                    Value = modifiedValue.BaseValue; 
                } 
            }
        } 

        internal void ResetCoercedValue()
        {
            if (IsCoerced) 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
                modifiedValue.CoercedValue = null; 
                IsCoerced = false;
 
                if (!HasModifiers)
                {
                    Value = modifiedValue.BaseValue;
                } 
            }
        } 
 
        // remove all modifiers, retain value source, and set value to supplied value
        internal void ResetValue(object value, bool hasExpressionMarker) 
        {
            _source &= FullValueSource.ValueSourceMask;
            _value = value;
            if (hasExpressionMarker) 
            {
                HasExpressionMarker = true; 
            } 
            Debug.Assert(hasExpressionMarker == (value == DependencyObject.ExpressionInAlternativeStore), "hasExpressionMarker flag must match value");
        } 

        // 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;
            }
            else
            { 
                object value = Value;
                Value = DependencyObject.ExpressionInAlternativeStore; 
                SetExpressionValue(value, DependencyObject.ExpressionInAlternativeStore); 
                _source |= FullValueSource.HasExpressionMarker;
            } 
        }


        #endregion InternalMethods 

        #region InternalProperties 
 
        public int PropertyIndex
        { 
            get { return _propertyIndex; }
            set { _propertyIndex = (short)value; }
        }
 
        /// 
        ///     If HasModifiers is true then it holds the value 
        ///     else it holds the modified value instance 
        /// 
        internal object Value 
        {
            get { return _value; }
            set { _value = value; }
        } 

        internal BaseValueSourceInternal BaseValueSourceInternal 
        { 
            get { return (BaseValueSourceInternal)(_source & FullValueSource.ValueSourceMask); }
            set { _source = (_source & ~FullValueSource.ValueSourceMask) | (FullValueSource)value; } 
        }

        internal bool IsDeferredReference
        { 
            get { return ReadPrivateFlag(FullValueSource.IsDeferredReference); }
            set { WritePrivateFlag(FullValueSource.IsDeferredReference, value); } 
        } 

        internal bool IsExpression 
        {
            get { return ReadPrivateFlag(FullValueSource.IsExpression); }
            private set { WritePrivateFlag(FullValueSource.IsExpression, value); }
        } 

        internal bool IsAnimated 
        { 
            get { return ReadPrivateFlag(FullValueSource.IsAnimated); }
            private set { WritePrivateFlag(FullValueSource.IsAnimated, value); } 
        }

        internal bool IsCoerced
        { 
            get { return ReadPrivateFlag(FullValueSource.IsCoerced); }
            private set { WritePrivateFlag(FullValueSource.IsCoerced, value); } 
        } 

        internal bool HasModifiers 
        {
            get { return (_source & FullValueSource.ModifiersMask) != 0; }
        }
 
        internal FullValueSource FullValueSource
        { 
            get { return _source; } 
        }
 

        internal bool HasExpressionMarker
        {
            get { return ReadPrivateFlag(FullValueSource.HasExpressionMarker); } 
            set { WritePrivateFlag(FullValueSource.HasExpressionMarker, value); }
        } 
 
        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 
            // 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 (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;

                // Deferred reference is possible only in the case of ResourceReferenceExpression
                // not when the expression originates from an alternate store. 
                if (!HasExpressionMarker && (entry.Value is DeferredReference))
                { 
                    entry.IsDeferredReference = true; 
                }
            } 

            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; 
        }
 
        internal void SetAnimationBaseValue(object animationBaseValue) 
        {
            if (!HasModifiers) 
            {
                Value = animationBaseValue;
            }
            else 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
 
                if (IsExpression)
                { 
                    modifiedValue.ExpressionValue = animationBaseValue;
                }
                else
                { 
                    modifiedValue.BaseValue = animationBaseValue;
                } 
            } 
        }
 
        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;
                } 
            }
        } 
 
        internal object LocalValue
        { 
            get
            {
                if (BaseValueSourceInternal == BaseValueSourceInternal.Local)
                { 
                    if (!HasModifiers)
                    { 
                        Debug.Assert(Value != DependencyProperty.UnsetValue); 
                        return Value;
                    } 
                    else
                    {
                        Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue);
                        return ModifiedValue.BaseValue; 
                    }
                } 
                else 
                {
                    return DependencyProperty.UnsetValue; 
                }
            }

            set 
            {
                Debug.Assert(BaseValueSourceInternal == BaseValueSourceInternal.Local, "This can happen only on an entry already having a local value"); 
 
                if (!HasModifiers)
                { 
                    Debug.Assert(Value != DependencyProperty.UnsetValue);
                    Value = value;
                }
                else 
                {
                    Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue); 
                    ModifiedValue.BaseValue = value; 
                }
            } 
        }

        internal ModifiedValue ModifiedValue
        { 
            get
            { 
                if (_value != null) 
                {
                    return _value as ModifiedValue; 
                }
                return null;
            }
        } 

        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;
        } 
 
        internal void Clear()
        { 
            _propertyIndex = -1;
            _value = null;
            _source = 0;
        } 

        #endregion InternalProperties 
 
        #region PrivateMethods
 
        private void WritePrivateFlag(FullValueSource bit, bool value)
        {
            if (value)
            { 
                _source |= bit;
            } 
            else 
            {
                _source &= ~bit; 
            }
        }

        private bool ReadPrivateFlag(FullValueSource bit) 
        {
            return (_source & bit) != 0; 
        } 

        #endregion PrivateMethods 

        #region Data

        private object                      _value; 
        private short                       _propertyIndex;
        private FullValueSource             _source; 
 
        #endregion Data
    } 


    [FriendAccessAllowed] // Built into Base, also used by Core & Framework.
    internal enum FullValueSource : short 
    {
        // Bit used to store BaseValueSourceInternal = 0x01 
        // Bit used to store BaseValueSourceInternal = 0x02 
        // Bit used to store BaseValueSourceInternal = 0x04
        // Bit used to store BaseValueSourceInternal = 0x08 

        ValueSourceMask     = 0x000F,
        ModifiersMask       = 0x0070,
        IsExpression        = 0x0010, 
        IsAnimated          = 0x0020,
        IsCoerced           = 0x0040, 
        IsDeferredReference = 0x0080, 
        HasExpressionMarker = 0x0100,
    } 

    // Note that these enum values are arranged in the reverse order of
    // precendence for these sources. Local value has highest
    // precedence and Default value has the least. Note that we do not 
    // store default values in the _effectiveValues cache unless it is
    // being coerced/animated. 
    [FriendAccessAllowed] // Built into Base, also used by Core & Framework. 
    internal enum BaseValueSourceInternal : short
    { 
        Unknown                 = 0,
        Default                 = 1,
        Inherited               = 2,
        ThemeStyle              = 3, 
        ThemeStyleTrigger       = 4,
        Style                   = 5, 
        TemplateTrigger         = 6, 
        StyleTrigger            = 7,
        ImplicitReference       = 8, 
        ParentTemplate          = 9,
        ParentTemplateTrigger   = 10,
        Local                   = 11,
    } 

    [FriendAccessAllowed] // Built into Base, also used by Core & Framework. 
    internal class ModifiedValue 
    {
        #region InternalProperties 

        internal object BaseValue
        {
            get { return _baseValue; } 
            set { _baseValue = value; }
        } 
 
        internal object ExpressionValue
        { 
            get { return _expressionValue; }
            set { _expressionValue = value; }
        }
 
        internal object AnimatedValue
        { 
            get { return _animatedValue; } 
            set { _animatedValue = value; }
        } 

        internal object CoercedValue
        {
            get { return _coercedValue; } 
            set { _coercedValue = value; }
        } 
 
        #endregion InternalProperties
 
        #region Data

        private object _baseValue;
        private object _expressionValue; 
        private object _animatedValue;
        private object _coercedValue; 
 
        #endregion Data
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: EffectiveValueEntry.cs
*
*  This file describes an entry in the EffectiveValues list held by a 
*  DependencyObject.
* 
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 

using MS.Internal.WindowsBase;  // FriendAccessAllowed
using System.Collections;       // IDictionary
using System.Diagnostics;       // Debug.Assert 

namespace System.Windows 
{ 
    [FriendAccessAllowed] // Built into Base, also used by Core & Framework.
    internal struct EffectiveValueEntry 
    {
        #region InternalMethods

        internal static EffectiveValueEntry CreateDefaultValueEntry(DependencyProperty dp, object value) 
        {
            EffectiveValueEntry entry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Default); 
            entry.Value = value; 
            return entry;
        } 

        internal EffectiveValueEntry(DependencyProperty dp)
        {
            _propertyIndex = (short) dp.GlobalIndex; 
            _value = null;
            _source = (FullValueSource) BaseValueSourceInternal.Unknown; 
        } 

        internal EffectiveValueEntry(DependencyProperty dp, BaseValueSourceInternal valueSource) 
        {
            _propertyIndex = (short) dp.GlobalIndex;
            _value = DependencyProperty.UnsetValue;
            _source = (FullValueSource) valueSource; 
        }
 
        internal EffectiveValueEntry(DependencyProperty dp, FullValueSource fullValueSource) 
        {
            _propertyIndex = (short) dp.GlobalIndex; 
            _value = DependencyProperty.UnsetValue;
            _source = fullValueSource;
        }
 
        internal void SetExpressionValue(object value, object baseValue)
        { 
            Debug.Assert(value != DependencyProperty.UnsetValue); 

            ModifiedValue modifiedValue = EnsureModifiedValue(); 
            modifiedValue.ExpressionValue = value;
            IsExpression = true;

            Debug.Assert(Object.Equals(modifiedValue.BaseValue, baseValue)); 
            Debug.Assert(!(baseValue is DeferredReference));
            Debug.Assert(IsDeferredReference == (value is DeferredReference)); 
        } 

        internal void SetAnimatedValue(object value, object baseValue) 
        {
            Debug.Assert((value != DependencyProperty.UnsetValue) &&
                         !(value is DeferredReference));
 
            ModifiedValue modifiedValue = EnsureModifiedValue();
            modifiedValue.AnimatedValue = value; 
            IsAnimated = true; 

            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)); 
        }
 
        internal void SetCoercedValue(object value, object baseValue, bool skipBaseValueChecks) 
        {
            Debug.Assert(value != DependencyProperty.UnsetValue && 
                         !(value is DeferredReference));

            ModifiedValue modifiedValue = EnsureModifiedValue();
            modifiedValue.CoercedValue = value; 
            IsCoerced = true;
 
            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 void ResetExpressionValue()
        { 
            if (IsExpression)
            {
                ModifiedValue modifiedValue = ModifiedValue;
                modifiedValue.ExpressionValue = null; 
                IsExpression = false;
 
                if (!HasModifiers) 
                {
                    Value = modifiedValue.BaseValue; 
                }
            }
        }
 
        internal void ResetAnimatedValue()
        { 
            if (IsAnimated) 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
                modifiedValue.AnimatedValue = null;
                IsAnimated = false;

                if (!HasModifiers) 
                {
                    Value = modifiedValue.BaseValue; 
                } 
            }
        } 

        internal void ResetCoercedValue()
        {
            if (IsCoerced) 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
                modifiedValue.CoercedValue = null; 
                IsCoerced = false;
 
                if (!HasModifiers)
                {
                    Value = modifiedValue.BaseValue;
                } 
            }
        } 
 
        // remove all modifiers, retain value source, and set value to supplied value
        internal void ResetValue(object value, bool hasExpressionMarker) 
        {
            _source &= FullValueSource.ValueSourceMask;
            _value = value;
            if (hasExpressionMarker) 
            {
                HasExpressionMarker = true; 
            } 
            Debug.Assert(hasExpressionMarker == (value == DependencyObject.ExpressionInAlternativeStore), "hasExpressionMarker flag must match value");
        } 

        // 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;
            }
            else
            { 
                object value = Value;
                Value = DependencyObject.ExpressionInAlternativeStore; 
                SetExpressionValue(value, DependencyObject.ExpressionInAlternativeStore); 
                _source |= FullValueSource.HasExpressionMarker;
            } 
        }


        #endregion InternalMethods 

        #region InternalProperties 
 
        public int PropertyIndex
        { 
            get { return _propertyIndex; }
            set { _propertyIndex = (short)value; }
        }
 
        /// 
        ///     If HasModifiers is true then it holds the value 
        ///     else it holds the modified value instance 
        /// 
        internal object Value 
        {
            get { return _value; }
            set { _value = value; }
        } 

        internal BaseValueSourceInternal BaseValueSourceInternal 
        { 
            get { return (BaseValueSourceInternal)(_source & FullValueSource.ValueSourceMask); }
            set { _source = (_source & ~FullValueSource.ValueSourceMask) | (FullValueSource)value; } 
        }

        internal bool IsDeferredReference
        { 
            get { return ReadPrivateFlag(FullValueSource.IsDeferredReference); }
            set { WritePrivateFlag(FullValueSource.IsDeferredReference, value); } 
        } 

        internal bool IsExpression 
        {
            get { return ReadPrivateFlag(FullValueSource.IsExpression); }
            private set { WritePrivateFlag(FullValueSource.IsExpression, value); }
        } 

        internal bool IsAnimated 
        { 
            get { return ReadPrivateFlag(FullValueSource.IsAnimated); }
            private set { WritePrivateFlag(FullValueSource.IsAnimated, value); } 
        }

        internal bool IsCoerced
        { 
            get { return ReadPrivateFlag(FullValueSource.IsCoerced); }
            private set { WritePrivateFlag(FullValueSource.IsCoerced, value); } 
        } 

        internal bool HasModifiers 
        {
            get { return (_source & FullValueSource.ModifiersMask) != 0; }
        }
 
        internal FullValueSource FullValueSource
        { 
            get { return _source; } 
        }
 

        internal bool HasExpressionMarker
        {
            get { return ReadPrivateFlag(FullValueSource.HasExpressionMarker); } 
            set { WritePrivateFlag(FullValueSource.HasExpressionMarker, value); }
        } 
 
        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 
            // 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 (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;

                // Deferred reference is possible only in the case of ResourceReferenceExpression
                // not when the expression originates from an alternate store. 
                if (!HasExpressionMarker && (entry.Value is DeferredReference))
                { 
                    entry.IsDeferredReference = true; 
                }
            } 

            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; 
        }
 
        internal void SetAnimationBaseValue(object animationBaseValue) 
        {
            if (!HasModifiers) 
            {
                Value = animationBaseValue;
            }
            else 
            {
                ModifiedValue modifiedValue = ModifiedValue; 
 
                if (IsExpression)
                { 
                    modifiedValue.ExpressionValue = animationBaseValue;
                }
                else
                { 
                    modifiedValue.BaseValue = animationBaseValue;
                } 
            } 
        }
 
        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;
                } 
            }
        } 
 
        internal object LocalValue
        { 
            get
            {
                if (BaseValueSourceInternal == BaseValueSourceInternal.Local)
                { 
                    if (!HasModifiers)
                    { 
                        Debug.Assert(Value != DependencyProperty.UnsetValue); 
                        return Value;
                    } 
                    else
                    {
                        Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue);
                        return ModifiedValue.BaseValue; 
                    }
                } 
                else 
                {
                    return DependencyProperty.UnsetValue; 
                }
            }

            set 
            {
                Debug.Assert(BaseValueSourceInternal == BaseValueSourceInternal.Local, "This can happen only on an entry already having a local value"); 
 
                if (!HasModifiers)
                { 
                    Debug.Assert(Value != DependencyProperty.UnsetValue);
                    Value = value;
                }
                else 
                {
                    Debug.Assert(ModifiedValue != null && ModifiedValue.BaseValue != DependencyProperty.UnsetValue); 
                    ModifiedValue.BaseValue = value; 
                }
            } 
        }

        internal ModifiedValue ModifiedValue
        { 
            get
            { 
                if (_value != null) 
                {
                    return _value as ModifiedValue; 
                }
                return null;
            }
        } 

        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;
        } 
 
        internal void Clear()
        { 
            _propertyIndex = -1;
            _value = null;
            _source = 0;
        } 

        #endregion InternalProperties 
 
        #region PrivateMethods
 
        private void WritePrivateFlag(FullValueSource bit, bool value)
        {
            if (value)
            { 
                _source |= bit;
            } 
            else 
            {
                _source &= ~bit; 
            }
        }

        private bool ReadPrivateFlag(FullValueSource bit) 
        {
            return (_source & bit) != 0; 
        } 

        #endregion PrivateMethods 

        #region Data

        private object                      _value; 
        private short                       _propertyIndex;
        private FullValueSource             _source; 
 
        #endregion Data
    } 


    [FriendAccessAllowed] // Built into Base, also used by Core & Framework.
    internal enum FullValueSource : short 
    {
        // Bit used to store BaseValueSourceInternal = 0x01 
        // Bit used to store BaseValueSourceInternal = 0x02 
        // Bit used to store BaseValueSourceInternal = 0x04
        // Bit used to store BaseValueSourceInternal = 0x08 

        ValueSourceMask     = 0x000F,
        ModifiersMask       = 0x0070,
        IsExpression        = 0x0010, 
        IsAnimated          = 0x0020,
        IsCoerced           = 0x0040, 
        IsDeferredReference = 0x0080, 
        HasExpressionMarker = 0x0100,
    } 

    // Note that these enum values are arranged in the reverse order of
    // precendence for these sources. Local value has highest
    // precedence and Default value has the least. Note that we do not 
    // store default values in the _effectiveValues cache unless it is
    // being coerced/animated. 
    [FriendAccessAllowed] // Built into Base, also used by Core & Framework. 
    internal enum BaseValueSourceInternal : short
    { 
        Unknown                 = 0,
        Default                 = 1,
        Inherited               = 2,
        ThemeStyle              = 3, 
        ThemeStyleTrigger       = 4,
        Style                   = 5, 
        TemplateTrigger         = 6, 
        StyleTrigger            = 7,
        ImplicitReference       = 8, 
        ParentTemplate          = 9,
        ParentTemplateTrigger   = 10,
        Local                   = 11,
    } 

    [FriendAccessAllowed] // Built into Base, also used by Core & Framework. 
    internal class ModifiedValue 
    {
        #region InternalProperties 

        internal object BaseValue
        {
            get { return _baseValue; } 
            set { _baseValue = value; }
        } 
 
        internal object ExpressionValue
        { 
            get { return _expressionValue; }
            set { _expressionValue = value; }
        }
 
        internal object AnimatedValue
        { 
            get { return _animatedValue; } 
            set { _animatedValue = value; }
        } 

        internal object CoercedValue
        {
            get { return _coercedValue; } 
            set { _coercedValue = value; }
        } 
 
        #endregion InternalProperties
 
        #region Data

        private object _baseValue;
        private object _expressionValue; 
        private object _animatedValue;
        private object _coercedValue; 
 
        #endregion Data
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK