EffectiveValueEntry.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / 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) 
        {
            Debug.Assert(value != DependencyProperty.UnsetValue && 
                         !(value is DeferredReference));

            ModifiedValue modifiedValue = EnsureModifiedValue();
            modifiedValue.CoercedValue = value; 
            IsCoerced = true;
 
            Debug.Assert(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 sync; 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