Beispiel #1
0
        internal static EffectiveValueEntry CreateDefaultValueEntry(DependencyProperty dp, object value)
        {
            EffectiveValueEntry entry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Default);

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

        }
        internal DependencyPropertyChangedEventArgs(
            DependencyProperty property,
            PropertyMetadata metadata,
            bool isAValueChange,
            EffectiveValueEntry oldEntry,
            EffectiveValueEntry newEntry,
            OperationType operationType)
        {
            _property = property;
            _metadata = metadata;
            _oldEntry = oldEntry;
            _newEntry = newEntry;

            _flags         = 0;
            _operationType = operationType;
            IsAValueChange = isAValueChange;

            // This is when a mutable default is promoted to a local value. On this operation mutable default
            // value acquires a freezable context. However this value promotion operation is triggered
            // whenever there has been a sub property change to the mutable default. Eg. Adding a TextEffect
            // to a TextEffectCollection instance which is the mutable default. Since we missed the sub property
            // change due to this add, we flip the IsASubPropertyChange bit on the following change caused by
            // the value promotion to coalesce these operations.
            IsASubPropertyChange = (operationType == OperationType.ChangeMutableDefaultValue);
        }
        internal DependencyPropertyChangedEventArgs(
            DependencyProperty  property, 
            PropertyMetadata    metadata,
            bool                isAValueChange, 
            EffectiveValueEntry oldEntry, 
            EffectiveValueEntry newEntry,
            OperationType       operationType) 
        {
            _property             = property;
            _metadata             = metadata;
            _oldEntry             = oldEntry; 
            _newEntry             = newEntry;
 
            _flags = 0; 
            _operationType        = operationType;
            IsAValueChange        = isAValueChange; 

            // This is when a mutable default is promoted to a local value. On this operation mutable default
            // value acquires a freezable context. However this value promotion operation is triggered
            // whenever there has been a sub property change to the mutable default. Eg. Adding a TextEffect 
            // to a TextEffectCollection instance which is the mutable default. Since we missed the sub property
            // change due to this add, we flip the IsASubPropertyChange bit on the following change caused by 
            // the value promotion to coalesce these operations. 
            IsASubPropertyChange = (operationType == OperationType.ChangeMutableDefaultValue);
        } 
 internal InheritablePropertyChangeInfo( 
     DependencyProperty  property,
     EffectiveValueEntry oldEntry, 
     EffectiveValueEntry newEntry)
 {
     _property = property;
     _oldEntry = oldEntry; 
     _newEntry = newEntry;
 } 
 internal InheritablePropertyChangeInfo(
     DependencyObject rootElement,
     DependencyProperty property,
     EffectiveValueEntry oldEntry,
     EffectiveValueEntry newEntry)
 {
     _rootElement = rootElement;
     _property    = property;
     _oldEntry    = oldEntry;
     _newEntry    = newEntry;
 }
 internal InheritablePropertyChangeInfo(
     DependencyObject rootElement,
     DependencyProperty  property, 
     EffectiveValueEntry oldEntry, 
     EffectiveValueEntry newEntry)
 {
     _rootElement = rootElement;
     _property = property;
     _oldEntry = oldEntry;
     _newEntry = newEntry;
 }
Beispiel #8
0
 // Token: 0x06000C66 RID: 3174 RVA: 0x0002E490 File Offset: 0x0002C690
 private static bool InvalidateTreeDependentProperty(TreeChangeInfo info, DependencyObject d, ref FrameworkObject fo, DependencyProperty dp, FrameworkPropertyMetadata fMetadata, Style selfStyle, Style selfThemeStyle, ref ChildRecord childRecord, bool isChildRecordValid, bool hasStyleChanged, bool isSelfInheritanceParent, bool wasSelfInheritanceParent)
 {
     if (!TreeWalkHelper.SkipNext(fo.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior)
     {
         InheritablePropertyChangeInfo rootInheritableValue = info.GetRootInheritableValue(dp);
         EffectiveValueEntry           oldEntry             = rootInheritableValue.OldEntry;
         EffectiveValueEntry           effectiveValueEntry  = info.IsAddOperation ? rootInheritableValue.NewEntry : new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited);
         bool flag = TreeWalkHelper.IsForceInheritedProperty(dp);
         if (d != info.Root)
         {
             if (wasSelfInheritanceParent)
             {
                 oldEntry = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences);
             }
             else if (isSelfInheritanceParent)
             {
                 EffectiveValueEntry valueEntry = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences);
                 if (valueEntry.BaseValueSourceInternal <= BaseValueSourceInternal.Inherited)
                 {
                     oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                     oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
                 }
                 else
                 {
                     oldEntry = valueEntry;
                 }
             }
             else
             {
                 oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                 oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
             }
         }
         else if (info.IsAddOperation && (flag || oldEntry.BaseValueSourceInternal <= BaseValueSourceInternal.Inherited))
         {
             EffectiveValueEntry valueEntry2 = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences);
             if (valueEntry2.BaseValueSourceInternal > BaseValueSourceInternal.Inherited)
             {
                 oldEntry = valueEntry2;
             }
         }
         OperationType operationType = info.IsAddOperation ? OperationType.AddChild : OperationType.RemoveChild;
         if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal)
         {
             return((d.UpdateEffectiveValue(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, oldEntry, ref effectiveValueEntry, false, false, operationType) & (UpdateResult)5) == UpdateResult.ValueChanged);
         }
         if (flag)
         {
             effectiveValueEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced);
             return((d.UpdateEffectiveValue(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, oldEntry, ref effectiveValueEntry, false, false, operationType) & (UpdateResult)5) == UpdateResult.ValueChanged);
         }
     }
     return(false);
 }
        internal DependencyPropertyChangedEventArgs(DependencyProperty property, PropertyMetadata metadata, object value)
        { 
            _property = property;
            _metadata = metadata;
            _oldEntry = new EffectiveValueEntry(property);
            _oldEntry.Value = value; 
            _newEntry = _oldEntry;
 
            _flags = 0; 
            _operationType = OperationType.Unknown;
            IsASubPropertyChange = true; 
        }
        internal DependencyPropertyChangedEventArgs(DependencyProperty property, PropertyMetadata metadata, object value)
        {
            _property       = property;
            _metadata       = metadata;
            _oldEntry       = new EffectiveValueEntry(property);
            _oldEntry.Value = value;
            _newEntry       = _oldEntry;

            _flags               = 0;
            _operationType       = OperationType.Unknown;
            IsASubPropertyChange = true;
        }
        /// <summary>
        ///     Initializes a new instance of the DependencyPropertyChangedEventArgs class.
        /// </summary>
        /// <param name="property">
        ///     The property whose value changed.
        /// </param>
        /// <param name="oldValue">
        ///     The value of the property before the change.
        /// </param>
        /// <param name="newValue">
        ///     The value of the property after the change.
        /// </param>
        public DependencyPropertyChangedEventArgs(DependencyProperty property, object oldValue, object newValue)
        {
            _property       = property;
            _metadata       = null;
            _oldEntry       = new EffectiveValueEntry(property);
            _newEntry       = _oldEntry;
            _oldEntry.Value = oldValue;
            _newEntry.Value = newValue;

            _flags         = 0;
            _operationType = OperationType.Unknown;
            IsAValueChange = true;
        }
        /// <summary>
        ///     Initializes a new instance of the DependencyPropertyChangedEventArgs class. 
        /// </summary>
        /// <param name="property"> 
        ///     The property whose value changed. 
        /// </param>
        /// <param name="oldValue"> 
        ///     The value of the property before the change.
        /// </param>
        /// <param name="newValue">
        ///     The value of the property after the change. 
        /// </param>
        public DependencyPropertyChangedEventArgs(DependencyProperty property, object oldValue, object newValue) 
        { 
            _property = property;
            _metadata = null; 
            _oldEntry = new EffectiveValueEntry(property);
            _newEntry = _oldEntry;
            _oldEntry.Value = oldValue;
            _newEntry.Value = newValue; 

            _flags = 0; 
            _operationType = OperationType.Unknown; 
            IsAValueChange        = true;
        } 
Beispiel #13
0
        [FriendAccessAllowed] // Declared in Base also used in Framework 
        internal UpdateResult UpdateEffectiveValue(
                EntryIndex          entryIndex,
                DependencyProperty  dp,
                PropertyMetadata    metadata, 
                EffectiveValueEntry oldEntry,
            ref EffectiveValueEntry newEntry, 
                bool                coerceWithDeferredReference, 
                bool                coerceWithCurrentValue,
                OperationType       operationType) 
        {
            if (dp == null)
            {
                throw new ArgumentNullException("dp"); 
            }
 
#region EventTracing 
#if VERBOSE_PROPERTY_EVENT
            bool isDynamicTracing = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); // This was under "normal" 
            if (isDynamicTracing)
            {
                ++InvalidationCount;
                if( InvalidationCount % 100 == 0 ) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYINVALIDATIONGUID, 
                                                         MS.Utility.EventType.Info, 
                                                         InvalidationCount );
                } 

                string TypeAndName = String.Format(CultureInfo.InvariantCulture, "[{0}]{1}({2})",GetType().Name,dp.Name,base.GetHashCode()); // FxCop wanted the CultureInfo.InvariantCulture

                EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYINVALIDATIONGUID, 
                                                     MS.Utility.EventType.StartEvent,
                                                     base.GetHashCode(), TypeAndName); // base.GetHashCode() to avoid calling a virtual, which FxCop doesn't like. 
            } 
#endif
 

#endregion EventTracing

#if NESTED_OPERATIONS_CHECK 
            // Are we invalidating out of control?
            if( NestedOperations > NestedOperationMaximum ) 
            { 
                // We're invalidating out of control, time to abort.
                throw new InvalidOperationException("Too many levels of nested DependencyProperty invalidations.  This usually indicates a circular reference in the application and the cycle needs to be broken."); 
            }
            NestedOperations++; // Decrement in the finally block
#endif
            int targetIndex = dp.GlobalIndex; 

            if (oldEntry.BaseValueSourceInternal == BaseValueSourceInternal.Unknown) 
            { 
                // Do a full get value of the old entry if it isn't supplied.
                // It isn't supplied in cases where we are *unsetting* a value 
                // (e.g. ClearValue, style unapply, trigger unapply)
                oldEntry = GetValueEntry(
                                    entryIndex,
                                    dp, 
                                    metadata,
                                    RequestFlags.RawEntry); 
            } 

            object oldValue = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value; 


            /*
            if( TraceDependencyProperty.IsEnabled ) 
            {
                TraceDependencyProperty.Trace( 
                    TraceEventType.Verbose, 
                    TraceDependencyProperty.UpdateEffectiveValueStart,
                    this, 
                    dp,
                    dp.OwnerType,
                    oldValue,
                    oldEntry.BaseValueSourceInternal ); 
            }
            */ 
 
            // for control-value coercion, extract the desired control value, then
            // reset the new entry to ask for a re-evaluation with coercion 
            object controlValue = null;
            if (coerceWithCurrentValue)
            {
                controlValue = newEntry.Value; 
                newEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced);
            } 
 
            // check for early-out opportunities:
            //  1) the new entry is of lower priority than the current entry 
            if ((newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Unknown) &&
                (newEntry.BaseValueSourceInternal < oldEntry.BaseValueSourceInternal))
            {
                return 0; 
            }
 
            bool isReEvaluate = false; 
            bool isCoerceValue = false;
            bool isClearValue = false; 

            if (newEntry.Value == DependencyProperty.UnsetValue)
            {
                FullValueSource fullValueSource = newEntry.FullValueSource; 
                isCoerceValue = (fullValueSource == FullValueSource.IsCoerced);
                isReEvaluate = true; 
 
                if (newEntry.BaseValueSourceInternal == BaseValueSourceInternal.Local)
                { 
                    isClearValue = true;
                }
            }
 
            // if we're not in an animation update (caused by AnimationStorage.OnCurrentTimeInvalidated)
            // then always force a re-evaluation if (a) there was an animation in play or (b) there's 
            // an expression evaluation to be made 
            if (isReEvaluate ||
                (!newEntry.IsAnimated && 
                 (oldEntry.IsAnimated ||
                 (oldEntry.IsExpression && newEntry.IsExpression && (newEntry.ModifiedValue.BaseValue == oldEntry.ModifiedValue.BaseValue)))))
            {
                // we have to compute the new value 
                if (!isCoerceValue)
                { 
                    newEntry = EvaluateEffectiveValue(entryIndex, dp, metadata, oldEntry, newEntry, operationType); 

                    // Make sure that the call out did not cause a change to entryIndex 
                    entryIndex = CheckEntryIndex(entryIndex, targetIndex);

                    bool found = (newEntry.Value != DependencyProperty.UnsetValue);
                    if (!found && metadata.IsInherited) 
                    {
                        DependencyObject inheritanceParent = InheritanceParent; 
                        if (inheritanceParent != null) 
                        {
                            // Fetch the IsDeferredValue flag from the InheritanceParent 
                            EntryIndex parentEntryIndex = inheritanceParent.LookupEntry(dp.GlobalIndex);
                            if (parentEntryIndex.Found)
                            {
                                found = true; 
                                newEntry = inheritanceParent._effectiveValues[parentEntryIndex.Index].GetFlattenedEntry(RequestFlags.FullyResolved);
                                newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; 
                            } 
                        }
                    } 

                    // interesting that I just had to add this ... suggests that we are now overinvalidating
                    if (!found)
                    { 
                        newEntry = EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(this, dp));
                    } 
                } 
                else
                { 
                    if (!oldEntry.HasModifiers)
                    {
                        newEntry = oldEntry;
                    } 
                    else
                    { 
                        newEntry = new EffectiveValueEntry(dp, oldEntry.BaseValueSourceInternal); 
                        ModifiedValue modifiedValue = oldEntry.ModifiedValue;
                        object baseValue = modifiedValue.BaseValue; 
                        newEntry.Value = baseValue;
                        newEntry.HasExpressionMarker = oldEntry.HasExpressionMarker;

                        if (oldEntry.IsExpression) 
                        {
                            newEntry.SetExpressionValue(modifiedValue.ExpressionValue, baseValue); 
                        } 

                        if (oldEntry.IsAnimated) 
                        {
                            newEntry.SetAnimatedValue(modifiedValue.AnimatedValue, baseValue);
                        }
                    } 
                }
            } 
 
            // Coerce to current value
            if (coerceWithCurrentValue) 
            {
                object baseValue = newEntry.GetFlattenedEntry(RequestFlags.CoercionBaseValue).Value;

                ProcessCoerceValue( 
                    dp,
                    metadata, 
                    ref entryIndex, 
                    ref targetIndex,
                    ref newEntry, 
                    ref oldEntry,
                    ref oldValue,
                    baseValue,
                    controlValue, 
                    null /*coerceValueCallback */,
                    coerceWithDeferredReference, 
                    coerceWithCurrentValue, 
                    false /*skipBaseValueChecks*/);
 
                // Make sure that the call out did not cause a change to entryIndex
                entryIndex = CheckEntryIndex(entryIndex, targetIndex);
            }
 
            // Coerce Value
            if (metadata.CoerceValueCallback != null && 
                !(isClearValue && newEntry.FullValueSource == (FullValueSource)BaseValueSourceInternal.Default)) 
            {
                // CALLBACK 
                object baseValue = newEntry.GetFlattenedEntry(RequestFlags.CoercionBaseValue).Value;

                ProcessCoerceValue(
                    dp, 
                    metadata,
                    ref entryIndex, 
                    ref targetIndex, 
                    ref newEntry,
                    ref oldEntry, 
                    ref oldValue,
                    baseValue,
                    null /* controlValue */,
                    metadata.CoerceValueCallback, 
                    coerceWithDeferredReference,
                    false /* coerceWithCurrentValue */, 
                    false /*skipBaseValueChecks*/); 

                // Make sure that the call out did not cause a change to entryIndex 
                entryIndex = CheckEntryIndex(entryIndex, targetIndex);
            }

            // The main difference between this callback and the metadata.CoerceValueCallback is that 
            // designers want to be able to coerce during all value changes including a change to the
            // default value. Whereas metadata.CoerceValueCallback coerces all property values but the 
            // default, because default values are meant to fit automatically fit into the coersion constraint. 

            if (dp.DesignerCoerceValueCallback != null) 
            {
                // During a DesignerCoerceValueCallback the value obtained is stored in the same
                // member as the metadata.CoerceValueCallback. In this case we do not store the
                // baseValue in the entry. Thus the baseValue checks will the violated. That is the 
                // reason for skipping these checks in this one case.
 
                // Also before invoking the DesignerCoerceValueCallback the baseValue must 
                // always be expanded if it is a DeferredReference
 
                ProcessCoerceValue(
                    dp,
                    metadata,
                    ref entryIndex, 
                    ref targetIndex,
                    ref newEntry, 
                    ref oldEntry, 
                    ref oldValue,
                    newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value, 
                    null /*controlValue*/,
                    dp.DesignerCoerceValueCallback,
                    false /*coerceWithDeferredReference*/,
                    false /*coerceWithCurrentValue*/, 
                    true /*skipBaseValueChecks*/);
 
                // Make sure that the call out did not cause a change to entryIndex 
                entryIndex = CheckEntryIndex(entryIndex, targetIndex);
            } 

            UpdateResult result = 0;

            if (newEntry.FullValueSource != (FullValueSource) BaseValueSourceInternal.Default) 
            {
                Debug.Assert(newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Unknown, "Value source should be known at this point"); 
                bool unsetValue = false; 

                if (newEntry.BaseValueSourceInternal == BaseValueSourceInternal.Inherited) 
                {
                    if (DependencyObject.IsTreeWalkOperation(operationType) &&
                        (newEntry.IsCoerced || newEntry.IsAnimated))
                    { 
                        // an inherited value has been coerced or animated.  This
                        // should be treated as a new "set" of the property. 
                        // The current tree walk should not continue into the subtree, 
                        // but rather a new tree walk should start.
 
                        // this signals OnPropertyChanged to start a new tree walk
                        // and mark the current node as SelfInheritanceParent
                        operationType = OperationType.Unknown;
 
                        // this signals the caller not to continue the current
                        // tree walk into the subtree 
                        result |= UpdateResult.InheritedValueOverridden; 
                    }
                    else if (!IsSelfInheritanceParent) 
                    {
                        // otherwise, just inherit the value from the InheritanceParent
                        unsetValue = true;
                    } 
                }
 
                if (unsetValue) 
                {
                    UnsetEffectiveValue(entryIndex, dp, metadata); 
                }
                else
                {
                    SetEffectiveValue(entryIndex, dp, metadata, newEntry, oldEntry); 
                }
            } 
            else 
            {
                UnsetEffectiveValue(entryIndex, dp, metadata); 
            }

            // Change notifications are fired when the value actually changed or in
            // the case of the Freezable mutable factories when the value source changes. 
            // Try AvaCop without the second condition to repro this problem.
            bool isAValueChange = !Equals(dp, oldValue, newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value); 
 
            if (isAValueChange)
            { 
                result |= UpdateResult.ValueChanged;
            }

            if (isAValueChange || 
                (operationType == OperationType.ChangeMutableDefaultValue && oldEntry.BaseValueSourceInternal != newEntry.BaseValueSourceInternal) ||
                (metadata.IsInherited && oldEntry.BaseValueSourceInternal != newEntry.BaseValueSourceInternal && operationType != OperationType.AddChild && operationType != OperationType.RemoveChild && operationType != OperationType.Inherit)) 
            { 
                result |= UpdateResult.NotificationSent;
 
                try
                {
                    // fire change notification
                    NotifyPropertyChange( 
                            new DependencyPropertyChangedEventArgs(
                                    dp, 
                                    metadata, 
                                    isAValueChange,
                                    oldEntry, 
                                    newEntry,
                                    operationType));
                }
                finally 
                {
#if NESTED_OPERATIONS_CHECK 
                    NestedOperations--; 
#endif
                } 
            }

#region EventTracing
#if VERBOSE_PROPERTY_EVENT 
            if (isDynamicTracing)
            { 
                if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYINVALIDATIONGUID, MS.Utility.EventType.EndEvent); 
                }
            }
#endif
#endregion EventTracing 

 
            /* 
            if( TraceDependencyProperty.IsEnabled )
            { 
                TraceDependencyProperty.Trace(
                    TraceEventType.Verbose,
                    TraceDependencyProperty.UpdateEffectiveValueStop,
                    this, dp, dp.OwnerType, 
                    newEntry.Value, newEntry.BaseValueSourceInternal );
            } 
            */ 

            // There are two cases in which we need to adjust inheritance contexts: 
            //
            //     1.  The value pointed to this DP has changed, in which case
            //         we need to move the context from the old value to the
            //         new value. 
            //
            //     2.  The value has not changed, but the ValueSource for the 
            //         property has.  (For example, we've gone from being a local 
            //         value to the result of a binding expression that just
            //         happens to return the same DO instance.)  In which case 
            //         we may need to add or remove contexts even though we
            //         did not raise change notifications.
            //
            // We don't want to provide an inheritance context if the entry is 
            // animated, coerced, is an expression, is coming from a style or
            // template, etc.  To avoid this, we explicitly check that the 
            // FullValueSource is Local.  By checking FullValueSource rather than 
            // BaseValueSource we are implicitly filtering out any sources which
            // have modifiers.  (e.g., IsExpression, IsAnimated, etc.) 

            bool oldEntryHadContext = oldEntry.FullValueSource == (FullValueSource) BaseValueSourceInternal.Local;
            bool newEntryNeedsContext = newEntry.FullValueSource == (FullValueSource) BaseValueSourceInternal.Local;
 
            // NOTE:  We use result rather than isAValueChange below so that we
            //        pick up mutable default promotion, etc. 
            if (result != 0 || (oldEntryHadContext != newEntryNeedsContext)) 
            {
                if (oldEntryHadContext) 
                {
                    // RemoveSelfAsInheritanceContext no-ops null, non-DO values, etc.
                    RemoveSelfAsInheritanceContext(oldEntry.LocalValue, dp);
                } 

                // Become the context for the new value. This is happens after 
                // invalidation so that FE has a chance to hookup the logical 
                // tree first. This is done only if the current DependencyObject
                // wants to be in the InheritanceContext tree. 
                if (newEntryNeedsContext)
                {
                    // ProvideSelfAsInheritanceContext no-ops null, non-DO values, etc.
                    ProvideSelfAsInheritanceContext(newEntry.LocalValue, dp); 
                }
 
                // DANGER:  Callout might add/remove entries in the effective value table. 
                //          Uncomment the following if you need to use entryIndex post
                //          context hookup. 
                //
                // entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);
            }
 
            return result;
        } 
Beispiel #14
0
        /// <summary> 
        ///     Invalidates a property
        /// </summary>
        /// <param name="dp">Dependency property</param>
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        public void InvalidateProperty(DependencyProperty dp)
        { 
            // Do not allow foreign threads access. 
            // (This is a noop if this object is not assigned to a Dispatcher.)
            // 
            this.VerifyAccess();

            if (dp == null)
            { 
                throw new ArgumentNullException("dp");
            } 
 
            EffectiveValueEntry newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Unknown);
 
            UpdateEffectiveValue(
                    LookupEntry(dp.GlobalIndex),
                    dp,
                    dp.GetMetadata(DependencyObjectType), 
                    new EffectiveValueEntry() /* oldEntry */,
                    ref newEntry, 
                    false /* coerceWithDeferredReference */, 
                    false /* coerceWithControlReference */,
                    OperationType.Unknown); 
        }
Beispiel #15
0
        /// <summary>
        ///     Coerce a property value 
        /// </summary> 
        /// <param name="dp">Dependency property</param>
        public void CoerceValue(DependencyProperty dp) 
        {
            // Do not allow foreign threads access.
            // (This is a noop if this object is not assigned to a Dispatcher.)
            // 
            this.VerifyAccess();
 
            EntryIndex entryIndex = LookupEntry(dp.GlobalIndex); 
            PropertyMetadata metadata = dp.GetMetadata(DependencyObjectType);
 
            // if the property has a coerced-with-control value, apply the coercion
            // to that value.  This is done by simply calling SetCurrentValue.
            if (entryIndex.Found)
            { 
                EffectiveValueEntry entry = GetValueEntry(entryIndex, dp, metadata, RequestFlags.RawEntry);
                if (entry.IsCoercedWithCurrentValue) 
                { 
                    SetCurrentValue(dp, entry.ModifiedValue.CoercedValue);
                    return; 
                }
            }

            // IsCoerced == true && value == UnsetValue indicates that we need to re-coerce this value 
            EffectiveValueEntry newEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced);
 
            UpdateEffectiveValue( 
                    entryIndex,
                    dp, 
                    metadata,
                    new EffectiveValueEntry() /* oldEntry */,
                    ref newEntry,
                    false /* coerceWithDeferredReference */, 
                    false /* coerceWithCurrentValue */,
                    OperationType.Unknown); 
        } 
Beispiel #16
0
        private bool ReceivePropertySet(object targetObject, XamlMember member,
            object value, DependencyObject templatedParent)
        {
            DependencyObject dependencyObject = targetObject as DependencyObject;
            DependencyProperty dependencyProperty;
            System.Windows.Baml2006.WpfXamlMember wpfMember = member as System.Windows.Baml2006.WpfXamlMember;
            if (wpfMember != null)
            {
                dependencyProperty = wpfMember.DependencyProperty;
            }
            else
            {
                // All DP backed XamlMembers must be wrapped by the WpfXamlMember.  If it isn't wrapped, then it's not a DP
                return false;
            }

            //If we're not dealing with a DO or a DP, we cannot set an EffectiveValueEntry
            if (dependencyProperty == null || dependencyObject == null)
            {
                return false;
            }

            FrameworkObject fo = new FrameworkObject(dependencyObject);

            // If this isn't an FE that we're optimizing, defer to base.
            //
            // Similarly, if we don't have a templated parent, we're not optimizing, and defer to base
            // (This happens when FrameworkTemplate.LoadContent() is called.)

            if ((fo.TemplatedParent == null) || (templatedParent == null))
            {
                return false;
            }

            // For template content, we skip the automatic BaseUriProperty and the UidProperty
            // (Implementation note:  Doing this here because this is what we did with FEFs,
            // and because automation gets confused if the Uid isn't unique in the whole tree).

            if (dependencyProperty == System.Windows.Navigation.BaseUriHelper.BaseUriProperty)
            {
                // We only skip the automatic BaseUri property.  If it's set explicitely,
                // that's passed through.

                if (!fo.IsInitialized)
                {
                    return true;
                }
            }

            else if (dependencyProperty == UIElement.UidProperty)
            {
                return true;
            }

            Debug.Assert(fo.TemplatedParent == templatedParent);

            // Set the value onto the FE/FCE.
            HybridDictionary parentTemplateValues;
            if (!fo.StoresParentTemplateValues)
            {
                parentTemplateValues = new HybridDictionary();
                StyleHelper.ParentTemplateValuesField.SetValue(dependencyObject, parentTemplateValues);
                fo.StoresParentTemplateValues = true;
            }
            else
            {
                parentTemplateValues = StyleHelper.ParentTemplateValuesField.GetValue(dependencyObject);
            }

            // Check if it is an expression

            Expression expr;
            int childIndex = fo.TemplateChildIndex;


            if ((expr = value as Expression) != null)
            {
                BindingExpressionBase bindingExpr;
                TemplateBindingExpression templateBindingExpr;

                if ((bindingExpr = expr as BindingExpressionBase) != null)
                {
                    // If this is a BindingExpression then we need to store the corresponding
                    // MarkupExtension into the per instance store for the unshared DP value.

                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions

                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, templatedParent, InstanceStyleData.InstanceValues);
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dependencyProperty, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/);

                    value = bindingExpr.ParentBindingBase;
                }
                else if ((templateBindingExpr = expr as TemplateBindingExpression) != null)
                {
                    // If this is a TemplateBindingExpression then we create an equivalent Binding
                    // MarkupExtension and store that in the per instance store for the unshared DP
                    // value. We use Binding here because it has all the wiring in place to handle
                    // change notifications through DependencySource and such.

                    TemplateBindingExtension templateBindingExtension = templateBindingExpr.TemplateBindingExtension;

                    // Allocate a slot for this unshared DP value in the per-instance store for MarkupExtensions

                    HybridDictionary instanceValues = StyleHelper.EnsureInstanceData(StyleHelper.TemplateDataField, templatedParent, InstanceStyleData.InstanceValues);
                    StyleHelper.ProcessInstanceValue(dependencyObject, childIndex, instanceValues, dependencyProperty, StyleHelper.UnsharedTemplateContentPropertyIndex, true /*apply*/);

                    // Create a Binding equivalent to the TemplateBindingExtension

                    Binding binding = new Binding();
                    binding.Mode = BindingMode.OneWay;
                    binding.RelativeSource = RelativeSource.TemplatedParent;
                    binding.Path = new PropertyPath(templateBindingExtension.Property);
                    binding.Converter = templateBindingExtension.Converter;
                    binding.ConverterParameter = templateBindingExtension.ConverterParameter;

                    value = binding;

                }
                else
                {
                    Debug.Assert(false, "We do not have support for DynamicResource within unshared template content");
                }
            }

            bool isMarkupExtension = value is MarkupExtension;
            // Value needs to be valid for the DP, or Binding/MultiBinding/PriorityBinding/TemplateBinding.
            if (!dependencyProperty.IsValidValue(value))
            {
                if (!isMarkupExtension && !(value is DeferredReference))
                {
                    throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, value, dependencyProperty.Name));
                }
            }

            parentTemplateValues[dependencyProperty] = value;

            dependencyObject.ProvideSelfAsInheritanceContext(value, dependencyProperty);

            EffectiveValueEntry entry = new EffectiveValueEntry(dependencyProperty);
            entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplate;
            entry.Value = value;

            if (isMarkupExtension)
            {
                // entry will be updated to hold the value
                StyleHelper.GetInstanceValue(
                            StyleHelper.TemplateDataField,
                            templatedParent,
                            fo.FE,
                            fo.FCE,
                            childIndex,
                            dependencyProperty,
                            StyleHelper.UnsharedTemplateContentPropertyIndex,
                            ref entry);
            }

            dependencyObject.UpdateEffectiveValue(
                    dependencyObject.LookupEntry(dependencyProperty.GlobalIndex),
                    dependencyProperty,
                    dependencyProperty.GetMetadata(dependencyObject.DependencyObjectType),
                    new EffectiveValueEntry() /* oldEntry */,
                ref entry,
                    false /* coerceWithDeferredReference */,
                    false /* coerceWithCurrentValue */,
                    OperationType.Unknown);

            return true;
        }
        internal sealed override void EvaluateAnimatedValueCore(
                DependencyProperty  dp,
                PropertyMetadata    metadata,
            ref EffectiveValueEntry entry)
        {
            if (IAnimatable_HasAnimatedProperties)
            {
                AnimationStorage storage = AnimationStorage.GetStorage(this, dp);

                if (storage != null)
                {
                    storage.EvaluateAnimatedValue(metadata, ref entry);                      
                }
            }
        }
Beispiel #18
0
        // Token: 0x06000C6D RID: 3181 RVA: 0x0002EB78 File Offset: 0x0002CD78
        private static bool OnInheritablePropertyChanged(DependencyObject d, InheritablePropertyChangeInfo info, bool visitedViaVisualTree)
        {
            DependencyProperty  property = info.Property;
            EffectiveValueEntry oldEntry = info.OldEntry;
            EffectiveValueEntry newEntry = info.NewEntry;
            InheritanceBehavior inheritanceBehavior;
            bool flag  = TreeWalkHelper.IsInheritanceNode(d, property, out inheritanceBehavior);
            bool flag2 = TreeWalkHelper.IsForceInheritedProperty(property);

            if (!flag || (TreeWalkHelper.SkipNext(inheritanceBehavior) && !flag2))
            {
                return(inheritanceBehavior == InheritanceBehavior.Default || flag2);
            }
            PropertyMetadata metadata   = property.GetMetadata(d);
            EntryIndex       entryIndex = d.LookupEntry(property.GlobalIndex);

            if (!d.IsSelfInheritanceParent)
            {
                DependencyObject    frameworkParent      = FrameworkElement.GetFrameworkParent(d);
                InheritanceBehavior inheritanceBehavior2 = InheritanceBehavior.Default;
                if (frameworkParent != null)
                {
                    FrameworkObject frameworkObject = new FrameworkObject(frameworkParent, true);
                    inheritanceBehavior2 = frameworkObject.InheritanceBehavior;
                }
                if (!TreeWalkHelper.SkipNext(inheritanceBehavior) && !TreeWalkHelper.SkipNow(inheritanceBehavior2))
                {
                    d.SynchronizeInheritanceParent(frameworkParent);
                }
                if (oldEntry.BaseValueSourceInternal == BaseValueSourceInternal.Unknown)
                {
                    oldEntry = EffectiveValueEntry.CreateDefaultValueEntry(property, metadata.GetDefaultValue(d, property));
                }
            }
            else
            {
                oldEntry = d.GetValueEntry(entryIndex, property, metadata, RequestFlags.RawEntry);
            }
            if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal)
            {
                if (visitedViaVisualTree && FrameworkElement.DType.IsInstanceOfType(d))
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(d);
                    if (parent != null)
                    {
                        DependencyObject parent2 = VisualTreeHelper.GetParent(d);
                        if (parent2 != null && parent2 != parent)
                        {
                            return(false);
                        }
                    }
                }
                return((d.UpdateEffectiveValue(entryIndex, property, metadata, oldEntry, ref newEntry, false, false, OperationType.Inherit) & (UpdateResult)5) == UpdateResult.ValueChanged);
            }
            if (flag2)
            {
                newEntry = new EffectiveValueEntry(property, FullValueSource.IsCoerced);
                return((d.UpdateEffectiveValue(d.LookupEntry(property.GlobalIndex), property, metadata, oldEntry, ref newEntry, false, false, OperationType.Inherit) & (UpdateResult)5) == UpdateResult.ValueChanged);
            }
            return(false);
        }
Beispiel #19
0
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 
        private EffectiveValueEntry EvaluateEffectiveValue(
            EntryIndex entryIndex,
            DependencyProperty dp,
            PropertyMetadata metadata, 
            EffectiveValueEntry oldEntry,
            EffectiveValueEntry newEntry, // this is only used to recognize if this is a clear local value 
            OperationType operationType) 
        {
#region EventTracing 
#if VERBOSE_PROPERTY_EVENT
            bool isDynamicTracing = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); // This was under "normal"
            if (isDynamicTracing)
            { 
                ++ValidationCount;
                if( ValidationCount % 100 == 0 ) 
                { 
                    EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYVALIDATIONGUID,
                                                         MS.Utility.EventType.Info, 
                                                         ValidationCount );
                }

                string TypeAndName = String.Format(CultureInfo.InvariantCulture, "[{0}]{1}({2})",GetType().Name,dp.Name,base.GetHashCode());  // FxCop wanted the CultureInfo.InvariantCulture 

                EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYVALIDATIONGUID, 
                                                     MS.Utility.EventType.StartEvent, 
                                                     base.GetHashCode(), TypeAndName ); // base.GetHashCode() to avoid calling a virtual, which FxCop doesn't like.
            } 
#endif
#endregion EventTracing

#if NESTED_OPERATIONS_CHECK 
            // Are we validating out of control?
            if( NestedOperations > NestedOperationMaximum ) 
            { 
                // We're validating out of control, time to abort.
                throw new InvalidOperationException("Too many levels of nested DependencyProperty GetValue calls.  This usually indicates a circular reference in the application and the cycle needs to be broken."); 
            }
            NestedOperations++; // Decrement in the finally block
#endif
 
            object value = DependencyProperty.UnsetValue;
 
            try 
            {
                // Read local storage 
                bool isSetValue = (newEntry.BaseValueSourceInternal == BaseValueSourceInternal.Local);
                bool isClearLocalValue = isSetValue && (newEntry.Value == DependencyProperty.UnsetValue);
                bool oldLocalIsExpression = false;
 
                if (isClearLocalValue)
                { 
                    newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Unknown; 
                }
                else 
                {
                    // if we reached this on a re-evaluate of a setvalue, we need to make sure
                    // we don't lose track of the newly specified local value.
                    // for all other cases, the oldEntry will have the local value we should 
                    // use.
                    value = isSetValue ? newEntry.LocalValue : oldEntry.LocalValue; 
 
                    if (value == ExpressionInAlternativeStore)
                    { 
                        value = DependencyProperty.UnsetValue;
                    }
                    else
                    { 
                        oldLocalIsExpression = isSetValue ? newEntry.IsExpression : oldEntry.IsExpression;
                    } 
                } 

                // (If local storage not Unset and not an Expression, return) 
                if (value != DependencyProperty.UnsetValue)
                {
                    newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Local);
                    newEntry.Value = value; 

                    // Check if an Expression is set 
                    if (oldLocalIsExpression) 
                    {
                        // CALLBACK 
                        newEntry = EvaluateExpression(
                            entryIndex,
                            dp,
                            (Expression) value, 
                            metadata,
                            oldEntry, 
                            newEntry); 

                        entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex); 

                        value = newEntry.ModifiedValue.ExpressionValue;
                    }
                } 

                // Subclasses are not allowed to resolve/modify the value for read-only properties. 
                if( !dp.ReadOnly ) 
                {
                    // Give subclasses a chance to resolve/modify the value 
                    EvaluateBaseValueCore(dp, metadata, ref newEntry);

                    // we need to have the default value in the entry before we do the animation check
                    if (newEntry.BaseValueSourceInternal == BaseValueSourceInternal.Unknown) 
                    {
                        newEntry = EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(this, dp)); 
                    } 

                    value = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value; 

                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);

                    if (oldEntry.IsAnimated) 
                    {
                        newEntry.ResetCoercedValue(); 
                        EvaluateAnimatedValueCore(dp, metadata, ref newEntry); 
                        value = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value;
                    } 
                }
            }
            finally
            { 
#if NESTED_OPERATIONS_CHECK
                NestedOperations--; 
#endif 
            }
 
#region EventTracing
#if VERBOSE_PROPERTY_EVENT
            if (isDynamicTracing)
            { 
                if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose))
                { 
                    int UsingDefault = 1; 
                    if (value != DependencyProperty.UnsetValue)
                        UsingDefault = 0; 
                    EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYVALIDATIONGUID,
                                                         MS.Utility.EventType.EndEvent,
                                                         UsingDefault);
                } 
            }
#endif 
#endregion EventTracing 

            if (value == DependencyProperty.UnsetValue) 
            {
                newEntry = EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(this, dp));
            }
 
            return newEntry;
        } 
Beispiel #20
0
        /// <summary> 
        ///     The common code shared by all variants of ClearValue 
        /// </summary>
        private void ClearValueCommon(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata) 
        {
            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.ClearOnReadOnlyObjectNotAllowed, this)); 
            }
 
            // Get old value 
            EffectiveValueEntry oldEntry = GetValueEntry(
                                        entryIndex, 
                                        dp,
                                        metadata,
                                        RequestFlags.RawEntry);
 
            // Get current local value
            // (No need to go through read local callback, just checking 
            // for presence of Expression) 
            object current = oldEntry.LocalValue;
 
            // Get current expression
            Expression currentExpr = (oldEntry.IsExpression) ? (current as Expression) : null;

            // Inform value expression of detachment, if applicable 
            if (currentExpr != null)
            { 
                // CALLBACK 
                DependencySource[] currentSources = currentExpr.GetSources();
 
                UpdateSourceDependentLists(this, dp, currentSources, currentExpr, false);  // Remove

                // CALLBACK
                currentExpr.OnDetach(this, dp); 
                currentExpr.MarkDetached();
                entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex); 
            } 

            // valuesource == Local && value == UnsetValue indicates that we are clearing the local value 
            EffectiveValueEntry newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Local);

            // Property is now invalid
            UpdateEffectiveValue( 
                    entryIndex,
                    dp, 
                    metadata, 
                    oldEntry,
                    ref newEntry, 
                    false /* coerceWithDeferredReference */,
                    false /* coerceWithCurrentValue */,
                    OperationType.Unknown);
        } 
Beispiel #21
0
        [FriendAccessAllowed] // Built into Base, also used by Core and Framework.
        internal void SetEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, int targetIndex, PropertyMetadata metadata, object value, BaseValueSourceInternal valueSource) 
        { 
            Debug.Assert(value != DependencyProperty.UnsetValue, "Value to be set cannot be UnsetValue");
            Debug.Assert(valueSource != BaseValueSourceInternal.Unknown, "ValueSource cannot be Unknown"); 

            // For thread-safety, sealed DOs can't modify _effectiveValues.
            Debug.Assert(!DO_Sealed, "A Sealed DO cannot be modified");
 
            if (metadata != null &&
                metadata.IsInherited && 
                valueSource != BaseValueSourceInternal.Inherited && 
                !IsSelfInheritanceParent)
            { 
                SetIsSelfInheritanceParent();
                entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);
            }
 
            EffectiveValueEntry entry;
            if (entryIndex.Found) 
            { 
                entry = _effectiveValues[entryIndex.Index];
            } 
            else
            {
                entry = new EffectiveValueEntry();
                entry.PropertyIndex = targetIndex; 
                InsertEntry(entry, entryIndex.Index);
                if (metadata != null && metadata.IsInherited) 
                { 
                    InheritableEffectiveValuesCount++;
                } 
            }

            bool hasExpressionMarker = (value == ExpressionInAlternativeStore);
 
            if (!hasExpressionMarker &&
                entry.HasExpressionMarker && 
                (valueSource == BaseValueSourceInternal.ThemeStyle || 
                 valueSource == BaseValueSourceInternal.ThemeStyleTrigger ||
                 valueSource == BaseValueSourceInternal.Style || 
                 valueSource == BaseValueSourceInternal.TemplateTrigger ||
                 valueSource == BaseValueSourceInternal.StyleTrigger ||
                 valueSource == BaseValueSourceInternal.ParentTemplate ||
                 valueSource == BaseValueSourceInternal.ParentTemplateTrigger)) 
            {
                entry.BaseValueSourceInternal = valueSource; 
                entry.SetExpressionValue(value, ExpressionInAlternativeStore); 
                entry.ResetAnimatedValue();
                entry.ResetCoercedValue(); 
            }
            else if (entry.IsExpression && entry.ModifiedValue.ExpressionValue == Expression.NoValue)
            {
                // we now have a value for an expression that is "hiding" - save it 
                // as the expression value
                entry.SetExpressionValue(value, entry.ModifiedValue.BaseValue); 
            } 
            else
            { 
                Debug.Assert(entry.BaseValueSourceInternal != BaseValueSourceInternal.Local || valueSource == BaseValueSourceInternal.Local,
                    "No one but another local value can stomp over an existing local value. The only way is to clear the entry");

                entry.BaseValueSourceInternal = valueSource; 
                entry.ResetValue(value, hasExpressionMarker);
            } 
 
            Debug.Assert(dp == null || (dp.GlobalIndex == entry.PropertyIndex), "EffectiveValueEntry & DependencyProperty do not match");
            _effectiveValues[entryIndex.Index] = entry; 
        }
Beispiel #22
0
        // insert the given entry at the given index
        // this function assumes that entryIndex is at the right
        // location such that the resulting list remains sorted by EffectiveValueEntry.PropertyIndex 
        private void InsertEntry(EffectiveValueEntry entry, uint entryIndex)
        { 
            // For thread-safety, sealed DOs can't modify _effectiveValues. 
            Debug.Assert(!DO_Sealed, "A Sealed DO cannot be modified");
 
#if DEBUG
            EntryIndex debugIndex = LookupEntry(entry.PropertyIndex);
            Debug.Assert(!debugIndex.Found && debugIndex.Index == entryIndex, "Inserting duplicate");
#endif 

            if (CanModifyEffectiveValues == false) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.LocalValueEnumerationInvalidated));
            } 

            uint effectiveValuesCount = EffectiveValuesCount;
            if (effectiveValuesCount > 0)
            { 
                if (_effectiveValues.Length == effectiveValuesCount)
                { 
                    int newSize = (int) (effectiveValuesCount * (IsInPropertyInitialization ? 2.0 : 1.2)); 
                    if (newSize == effectiveValuesCount)
                    { 
                        newSize++;
                    }

                    EffectiveValueEntry[] destEntries = new EffectiveValueEntry[newSize]; 
                    Array.Copy(_effectiveValues, 0, destEntries, 0, entryIndex);
                    destEntries[entryIndex] = entry; 
                    Array.Copy(_effectiveValues, entryIndex, destEntries, entryIndex + 1, effectiveValuesCount - entryIndex); 
                    _effectiveValues = destEntries;
                } 
                else
                {
                    Array.Copy(_effectiveValues, entryIndex, _effectiveValues, entryIndex + 1, effectiveValuesCount - entryIndex);
                    _effectiveValues[entryIndex] = entry; 
                }
            } 
            else 
            {
                if (_effectiveValues == null) 
                {
                    _effectiveValues = new EffectiveValueEntry[EffectiveValuesInitialSize];
                }
                _effectiveValues[0] = entry; 
            }
            EffectiveValuesCount = effectiveValuesCount + 1; 
        } 
Beispiel #23
0
 /// <summary> 
 ///     Allows subclasses to participate in property animated value computation
 /// </summary>
 internal virtual void EvaluateAnimatedValueCore(
         DependencyProperty  dp, 
         PropertyMetadata    metadata,
     ref EffectiveValueEntry newEntry) 
 { 
 }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        private void ProcessCoerceValue(
            DependencyProperty dp, 
            PropertyMetadata metadata,
            ref EntryIndex entryIndex,
            ref int targetIndex,
            ref EffectiveValueEntry newEntry, 
            ref EffectiveValueEntry oldEntry,
            ref object oldValue, 
            object baseValue, 
            object controlValue,
            CoerceValueCallback coerceValueCallback, 
            bool coerceWithDeferredReference,
            bool coerceWithCurrentValue,
            bool skipBaseValueChecks)
        { 
            if (newEntry.IsDeferredReference)
            { 
                Debug.Assert(!(newEntry.IsCoerced && !newEntry.IsCoercedWithCurrentValue) && 
                    !newEntry.IsAnimated, "Coerced or Animated value cannot be a deferred reference");
 
                // Allow values to stay deferred through coercion callbacks in
                // limited circumstances, when we know the listener is internal.
                // Since we never assign DeferredReference instances to
                // non-internal (non-friend assembly) classes, it's safe to skip 
                // the dereference if the callback is to the DP owner (and not
                // a derived type).  This is consistent with passing raw 
                // DeferredReference instances to ValidateValue callbacks, which 
                // only ever go to the owner class.
                if (!coerceWithDeferredReference || 
                    dp.OwnerType != metadata.CoerceValueCallback.Method.DeclaringType) // Need 2nd check to rule out derived class callback overrides.
                {
                    // Resolve deferred references because we need the actual
                    // baseValue to evaluate the correct animated value. This is done 
                    // by invoking GetValue for this property.
                    DeferredReference dr = (DeferredReference) baseValue; 
                    baseValue = dr.GetValue(newEntry.BaseValueSourceInternal); 

                    // Set the baseValue back into the entry 
                    newEntry.SetCoersionBaseValue(baseValue);

                    entryIndex = CheckEntryIndex(entryIndex, targetIndex);
                } 
            }
 
            object coercedValue = coerceWithCurrentValue ? controlValue : coerceValueCallback(this, baseValue); 

            // Make sure that the call out did not cause a change to entryIndex 
            entryIndex = CheckEntryIndex(entryIndex, targetIndex);

            // Even if we used the controlValue in the coerce callback, we still want to compare against the original baseValue
            // to determine if we need to set a coerced value. 
            if (!Equals(dp, coercedValue, baseValue))
            { 
                // returning DependencyProperty.UnsetValue from a Coercion callback means "don't do the set" ... 
                // or "use previous value"
                if (coercedValue == DependencyProperty.UnsetValue) 
                {
                    if (oldEntry.IsDeferredReference)
                    {
                        DeferredReference reference = (DeferredReference)oldValue; 
                        oldValue = reference.GetValue(oldEntry.BaseValueSourceInternal);
 
                        entryIndex = CheckEntryIndex(entryIndex, targetIndex); 
                    }
 
                    coercedValue = oldValue;
                }

                // Note that we do not support the value being coerced to a 
                // DeferredReference
                if (!dp.IsValidValue(coercedValue)) 
                { 
                    // well... unless it's the control's "current value"
                    if (!(coerceWithCurrentValue && coercedValue is DeferredReference)) 
                        throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, coercedValue, dp.Name));
                }

                // Set the coerced value here. All other values would 
                // have been set during EvaluateEffectiveValue/GetValueCore.
 
                newEntry.SetCoercedValue(coercedValue, baseValue, skipBaseValueChecks, coerceWithCurrentValue); 
            }
        } 
Beispiel #26
0
        /// <summary>
        ///     Callback on visiting each node in the descendency 
        ///     during an inheritable property change
        /// </summary>
        private static bool OnInheritablePropertyChanged(
            DependencyObject              d, 
            InheritablePropertyChangeInfo info)
        { 
            Debug.Assert(d != null, "Must have non-null current node"); 

            DependencyProperty dp = info.Property; 
            EffectiveValueEntry oldEntry = info.OldEntry;
            EffectiveValueEntry newEntry = info.NewEntry;

            InheritanceBehavior inheritanceBehavior; 
            bool inheritanceNode = IsInheritanceNode(d, dp, out inheritanceBehavior);
            bool isForceInheritedProperty = IsForceInheritedProperty(dp); 
 
            // Note that if a node is marked SkipNext means it hasn't acquired any values from its parent and
            // hence we do not need to invalidate this node or any of its descendents. However if a node is 
            // marked SkipNow then this node might have acquired values from its parent but none of its
            // descendents would. Hence in this case we process the current node but omit all of its descendents.
            if (inheritanceNode && (!SkipNext(inheritanceBehavior) || isForceInheritedProperty))
            { 
                PropertyMetadata metadata = dp.GetMetadata(d);
                EntryIndex entryIndex = d.LookupEntry(dp.GlobalIndex); 
 
                // Found an inheritance node
                if (!d.IsSelfInheritanceParent) 
                {
                    DependencyObject parent = FrameworkElement.GetFrameworkParent(d);
                    InheritanceBehavior parentInheritanceBehavior = InheritanceBehavior.Default;
 
                    if (parent != null)
                    { 
                        FrameworkObject parentFO = new FrameworkObject(parent, true); 
                        parentInheritanceBehavior = parentFO.InheritanceBehavior;
                    } 

                    if (!SkipNext(inheritanceBehavior) && !SkipNow(parentInheritanceBehavior))
                    {
                        // Synchronize InheritanceParent 
                        d.SynchronizeInheritanceParent(parent);
                    } 
 
                    // What should the oldValueSource on the child be?
                    // When the oldValue on the parent was default it 
                    // means that the child also used its own default
                    // and did not inherit from the parent. However
                    // when the value on the parent was non-default
                    // it means that the child inherited it. 
                    // Note that the oldValueSource on inheritablePropertyChangedData
                    // is actually the parent's oldValueSource 
 
                    if (oldEntry.BaseValueSourceInternal == BaseValueSourceInternal.Unknown)
                    { 
                        // we use an empty EffectiveValueEntry as a signal that the old entry was the default value
                        oldEntry = EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(d, dp));
                    }
                } 
                else
                { 
                    oldEntry = d.GetValueEntry( 
                                        entryIndex,
                                        dp, 
                                        metadata,
                                        RequestFlags.RawEntry);
                 }
 
                // If the oldValueSource is of lower precedence than Inheritance
                // only then do we need to Invalidate the property 
                if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal) 
                {
                    // Since we do not hold a cache of the oldValue we need to supply one 
                    // in order to correctly fire the change notification
                    return (d.UpdateEffectiveValue(
                            entryIndex,
                            dp, 
                            metadata,
                            oldEntry, 
                            ref newEntry, 
                            false /* coerceWithDeferredReference */,
                            false /* coerceWithCurrentValue */, 
                            OperationType.Inherit)
                        & (UpdateResult.ValueChanged | UpdateResult.InheritedValueOverridden))
                        == UpdateResult.ValueChanged;
                    // return false if either the value didn't change or 
                    // it changed because the inherited value was overridden by coercion or animation.
                } 
                else if (isForceInheritedProperty) 
                {
                    // IsCoerced == true && value == UnsetValue indicates that we need to re-coerce this value 
                    newEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced);

                    // Re-coerce a force inherited property because it's coersion depends on treeness
                    return (d.UpdateEffectiveValue( 
                            d.LookupEntry(dp.GlobalIndex),
                            dp, 
                            metadata, 
                            oldEntry,
                            ref newEntry, 
                            false /* coerceWithDeferredReference */,
                            false /* coerceWithCurrentValue */,
                            OperationType.Inherit)
                        & (UpdateResult.ValueChanged | UpdateResult.InheritedValueOverridden)) 
                        == UpdateResult.ValueChanged;
                    // return false if either the value didn't change or 
                    // it changed because the inherited value was overridden by coercion or animation. 
                }
                else 
                {
                    return false;
                }
            } 

            // Do not continue walk down subtree if the walk was forced to stop 
            // (due to separated trees) 
            return (inheritanceBehavior == InheritanceBehavior.Default || isForceInheritedProperty);
        } 
Beispiel #27
0
        private EffectiveValueEntry EvaluateExpression( 
            EntryIndex entryIndex,
            DependencyProperty dp, 
            Expression expr,
            PropertyMetadata metadata,
            EffectiveValueEntry oldEntry,
            EffectiveValueEntry newEntry) 
        {
            object value = expr.GetValue(this, dp); 
            bool isDeferredReference = false; 

            if (value != DependencyProperty.UnsetValue && value != Expression.NoValue) 
            {
                isDeferredReference = (value is DeferredReference);
                if (!isDeferredReference && !dp.IsValidValue(value))
                { 
#region EventTracing
#if VERBOSE_PROPERTY_EVENT 
                    if (isDynamicTracing) 
                    {
                        if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose)) 
                        {
                            EventTrace.EventProvider.TraceEvent(EventTrace.PROPERTYGUID,
                                                                MS.Utility.EventType.EndEvent,
                                                                EventTrace.PROPERTYVALIDATION, 0xFFF ); 
                        }
                    } 
#endif 
#endregion EventTracing
                    throw new InvalidOperationException(SR.Get(SRID.InvalidPropertyValue, value, dp.Name)); 
                }
            }
            else
            { 
                if (value == Expression.NoValue)
                { 
                    // The expression wants to "hide".  First set the 
                    // expression value to NoValue to indicate "hiding".
                    newEntry.SetExpressionValue(Expression.NoValue, expr); 

                    // Next, get the expression value some other way.
                    if (!dp.ReadOnly)
                    { 
                        EvaluateBaseValueCore(dp, metadata, ref newEntry);
                        value = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved).Value; 
                    } 
                    else
                    { 
                        value = DependencyProperty.UnsetValue;
                    }
                }
 
                // if there is still no value, use the default
                if (value == DependencyProperty.UnsetValue) 
                { 
                    value = metadata.GetDefaultValue(this, dp);
                } 
            }

            // Set the expr and its evaluated value into
            // the _effectiveValues cache 
            newEntry.SetExpressionValue(value, expr);
            return newEntry; 
        } 
Beispiel #28
0
        // Token: 0x06000C59 RID: 3161 RVA: 0x0002DFDC File Offset: 0x0002C1DC
        internal FrugalObjectList <DependencyProperty> CreateParentInheritableProperties(DependencyObject d, DependencyObject parent, bool isAddOperation)
        {
            if (parent == null)
            {
                return(new FrugalObjectList <DependencyProperty>(0));
            }
            DependencyObjectType dependencyObjectType = d.DependencyObjectType;

            EffectiveValueEntry[] array = null;
            uint num  = 0U;
            uint num2 = 0U;

            if (!parent.IsSelfInheritanceParent)
            {
                DependencyObject inheritanceParent = parent.InheritanceParent;
                if (inheritanceParent != null)
                {
                    array = inheritanceParent.EffectiveValues;
                    num   = inheritanceParent.EffectiveValuesCount;
                    num2  = inheritanceParent.InheritableEffectiveValuesCount;
                }
            }
            else
            {
                array = parent.EffectiveValues;
                num   = parent.EffectiveValuesCount;
                num2  = parent.InheritableEffectiveValuesCount;
            }
            FrugalObjectList <DependencyProperty> frugalObjectList = new FrugalObjectList <DependencyProperty>((int)num2);

            if (num2 == 0U)
            {
                return(frugalObjectList);
            }
            this._rootInheritableValues = new InheritablePropertyChangeInfo[num2];
            int             num3            = 0;
            FrameworkObject frameworkObject = new FrameworkObject(parent);

            for (uint num4 = 0U; num4 < num; num4 += 1U)
            {
                EffectiveValueEntry effectiveValueEntry = array[(int)num4];
                DependencyProperty  dependencyProperty  = DependencyProperty.RegisteredPropertyList.List[effectiveValueEntry.PropertyIndex];
                if (dependencyProperty != null && dependencyProperty.IsPotentiallyInherited)
                {
                    PropertyMetadata metadata = dependencyProperty.GetMetadata(parent.DependencyObjectType);
                    if (metadata != null && metadata.IsInherited)
                    {
                        FrameworkPropertyMetadata frameworkPropertyMetadata = (FrameworkPropertyMetadata)metadata;
                        if (!TreeWalkHelper.SkipNow(frameworkObject.InheritanceBehavior) || frameworkPropertyMetadata.OverridesInheritanceBehavior)
                        {
                            frugalObjectList.Add(dependencyProperty);
                            EffectiveValueEntry valueEntry = d.GetValueEntry(d.LookupEntry(dependencyProperty.GlobalIndex), dependencyProperty, dependencyProperty.GetMetadata(dependencyObjectType), RequestFlags.DeferredReferences);
                            EffectiveValueEntry newEntry;
                            if (isAddOperation)
                            {
                                newEntry = effectiveValueEntry;
                                if (newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default || newEntry.HasModifiers)
                                {
                                    newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                                    newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
                                }
                            }
                            else
                            {
                                newEntry = default(EffectiveValueEntry);
                            }
                            this._rootInheritableValues[num3++] = new InheritablePropertyChangeInfo(d, dependencyProperty, valueEntry, newEntry);
                            if ((ulong)num2 == (ulong)((long)num3))
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return(frugalObjectList);
        }
Beispiel #29
0
        [FriendAccessAllowed] // Built into Base, also used by Core.
        internal EffectiveValueEntry GetValueEntry( 
            EntryIndex          entryIndex,
            DependencyProperty  dp,
            PropertyMetadata    metadata,
            RequestFlags        requests) 
        {
            EffectiveValueEntry entry; 
 
            if (dp.ReadOnly)
            { 
                if (metadata == null)
                {
                    metadata = dp.GetMetadata(DependencyObjectType);
                } 

                GetReadOnlyValueCallback getValueCallback = metadata.GetReadOnlyValueCallback; 
                if (getValueCallback != null) 
                {
                    BaseValueSourceInternal valueSource; 
                    entry = new EffectiveValueEntry(dp);
                    entry.Value = getValueCallback(this, out valueSource);
                    entry.BaseValueSourceInternal = valueSource;
                    return entry; 
                }
            } 
 
            if (entryIndex.Found)
            { 
                if ((requests & RequestFlags.RawEntry) != 0)
                {
                    entry = _effectiveValues[entryIndex.Index];
                } 
                else
                { 
                    entry = GetEffectiveValue( 
                                entryIndex,
                                dp, 
                                requests);
                }
            }
            else 
            {
                entry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Unknown); 
            } 

            if (entry.Value == DependencyProperty.UnsetValue) 
            {
                if (dp.IsPotentiallyInherited)
                {
                    if (metadata == null) 
                    {
                        metadata = dp.GetMetadata(DependencyObjectType); 
                    } 

                    if (metadata.IsInherited) 
                    {
                        DependencyObject inheritanceParent = InheritanceParent;
                        if (inheritanceParent != null)
                        { 
                            entryIndex = inheritanceParent.LookupEntry(dp.GlobalIndex);
 
                            if (entryIndex.Found) 
                            {
                                entry = inheritanceParent.GetEffectiveValue( 
                                                entryIndex,
                                                dp,
                                                requests & RequestFlags.DeferredReferences);
                                entry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; 
                            }
                        } 
                    } 

                    if (entry.Value != DependencyProperty.UnsetValue) 
                    {
                        return entry;
                    }
                } 

                if ((requests & RequestFlags.SkipDefault) == 0) 
                { 
                    if (dp.IsPotentiallyUsingDefaultValueFactory)
                    { 
                        if (metadata == null)
                        {
                            metadata = dp.GetMetadata(DependencyObjectType);
                        } 

                        if (((requests & (RequestFlags.DeferredReferences | RequestFlags.RawEntry)) != 0) && metadata.UsingDefaultValueFactory) 
                        { 
                            entry.BaseValueSourceInternal = BaseValueSourceInternal.Default;
 
                            entry.Value = new DeferredMutableDefaultReference(metadata, this, dp);
                            return entry;
                        }
                    } 
                    else if (!dp.IsDefaultValueChanged)
                    { 
                        return EffectiveValueEntry.CreateDefaultValueEntry(dp, dp.DefaultMetadata.DefaultValue); 
                    }
 
                    if (metadata == null)
                    {
                        metadata = dp.GetMetadata(DependencyObjectType);
                    } 

                    return EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(this, dp)); 
                } 
            }
            return entry; 
        }
        //
        //  This method
        //  1. Is called from AncestorChange InvalidateTree.
        //  2. It is used to create the InheritableProperties on the given node.
        //  3. It also accumulates oldValues for the inheritable properties that are about to be invalidated
        //
        internal FrugalObjectList <DependencyProperty> CreateParentInheritableProperties(
            DependencyObject d,
            DependencyObject parent,
            bool isAddOperation)
        {
            Debug.Assert(d != null, "Must have non-null current node");

            if (parent == null)
            {
                return(new FrugalObjectList <DependencyProperty>(0));
            }

            DependencyObjectType treeObjDOT = d.DependencyObjectType;

            // See if we have a cached value.
            EffectiveValueEntry[] parentEffectiveValues = null;
            uint parentEffectiveValuesCount             = 0;
            uint inheritablePropertiesCount             = 0;

            // If inheritable properties aren't cached on you then use the effective
            // values cache on the parent to discover those inherited properties that
            // may need to be invalidated on the children nodes.
            if (!parent.IsSelfInheritanceParent)
            {
                DependencyObject inheritanceParent = parent.InheritanceParent;
                if (inheritanceParent != null)
                {
                    parentEffectiveValues      = inheritanceParent.EffectiveValues;
                    parentEffectiveValuesCount = inheritanceParent.EffectiveValuesCount;
                    inheritablePropertiesCount = inheritanceParent.InheritableEffectiveValuesCount;
                }
            }
            else
            {
                parentEffectiveValues      = parent.EffectiveValues;
                parentEffectiveValuesCount = parent.EffectiveValuesCount;
                inheritablePropertiesCount = parent.InheritableEffectiveValuesCount;
            }

            FrugalObjectList <DependencyProperty> inheritableProperties = new FrugalObjectList <DependencyProperty>((int)inheritablePropertiesCount);

            if (inheritablePropertiesCount == 0)
            {
                return(inheritableProperties);
            }

            _rootInheritableValues = new InheritablePropertyChangeInfo[(int)inheritablePropertiesCount];
            int inheritableIndex = 0;

            FrameworkObject foParent = new FrameworkObject(parent);

            for (uint i = 0; i < parentEffectiveValuesCount; i++)
            {
                // Add all the inheritable properties from the effectiveValues
                // cache to the TreeStateCache on the parent
                EffectiveValueEntry entry = parentEffectiveValues[i];
                DependencyProperty  dp    = DependencyProperty.RegisteredPropertyList.List[entry.PropertyIndex];

                // There are UncommonFields also stored in the EffectiveValues cache. We need to exclude those.
                if ((dp != null) && dp.IsPotentiallyInherited)
                {
                    PropertyMetadata metadata = dp.GetMetadata(parent.DependencyObjectType);
                    if (metadata != null && metadata.IsInherited)
                    {
                        Debug.Assert(!inheritableProperties.Contains(dp), "EffectiveValues cache must not contains duplicate entries for the same DP");

                        FrameworkPropertyMetadata fMetadata = (FrameworkPropertyMetadata)metadata;

                        // Children do not need to inherit properties across a tree boundary
                        // unless the property is set to override this behavior.

                        if (!TreeWalkHelper.SkipNow(foParent.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior)
                        {
                            inheritableProperties.Add(dp);

                            EffectiveValueEntry oldEntry;
                            EffectiveValueEntry newEntry;

                            oldEntry = d.GetValueEntry(
                                d.LookupEntry(dp.GlobalIndex),
                                dp,
                                dp.GetMetadata(treeObjDOT),
                                RequestFlags.DeferredReferences);

                            if (isAddOperation)
                            {
                                // set up the new value
                                newEntry = entry;

                                if ((newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default) || newEntry.HasModifiers)
                                {
                                    newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                                    newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
                                }
                            }
                            else
                            {
                                newEntry = new EffectiveValueEntry();
                            }


                            _rootInheritableValues[inheritableIndex++] =
                                new InheritablePropertyChangeInfo(d, dp, oldEntry, newEntry);

                            if (inheritablePropertiesCount == inheritableIndex)
                            {
                                // no more inheritable properties, bail early
                                break;
                            }
                        }
                    }
                }
            }

            return(inheritableProperties);
        }
Beispiel #31
0
        [FriendAccessAllowed] // Built into Base, also used by Core and Framework.
        internal void EndPropertyInitialization()
        { 
            IsInPropertyInitialization = false;
 
            if (_effectiveValues != null) 
            {
                uint effectiveValuesCount = EffectiveValuesCount; 
                if (effectiveValuesCount != 0)
                {
                    uint endLength = effectiveValuesCount;
                    if (((float) endLength / (float) _effectiveValues.Length) < 0.8) 
                    {
                        // For thread-safety, sealed DOs can't modify _effectiveValues. 
                        Debug.Assert(!DO_Sealed, "A Sealed DO cannot be modified"); 

                        EffectiveValueEntry[] destEntries = new EffectiveValueEntry[endLength]; 
                        Array.Copy(_effectiveValues, 0, destEntries, 0, effectiveValuesCount);
                        _effectiveValues = destEntries;
                    }
                } 
            }
        } 
        /// <summary> 
        ///     Allows subclasses to participate in property base value computation
        /// </summary>
        /// <param name="dp">Dependency property</param>
        /// <param name="metadata">Type metadata of the property for the type</param> 
        /// <param name="newEntry">entry computed by base</param>
        internal sealed override void EvaluateBaseValueCore( 
            DependencyProperty  dp, 
            PropertyMetadata    metadata,
            ref EffectiveValueEntry newEntry) 
        {
            if (dp == StyleProperty)
            {
                // If this is the first time that the StyleProperty 
                // is being fetched then mark it such
                HasStyleEverBeenFetched = true; 
 
                // Clear the flags associated with the StyleProperty
                HasImplicitStyleFromResources = false; 
                IsStyleSetFromGenerator = false;
            }

            GetRawValue(dp, metadata, ref newEntry); 
            Storyboard.GetComplexPathValue(this, dp, ref newEntry, metadata);
        } 
Beispiel #33
0
        internal void SetEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry newEntry, EffectiveValueEntry oldEntry) 
        {
            if (metadata != null && 
                metadata.IsInherited && 
                (newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Inherited ||
                    newEntry.IsCoerced || newEntry.IsAnimated) && 
                !IsSelfInheritanceParent)
            {
                SetIsSelfInheritanceParent();
                entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex); 
            }
 
            bool restoreMarker = false; 

            if (oldEntry.HasExpressionMarker && !newEntry.HasExpressionMarker) 
            {
                BaseValueSourceInternal valueSource = newEntry.BaseValueSourceInternal;
                restoreMarker = (valueSource == BaseValueSourceInternal.ThemeStyle ||
                                 valueSource == BaseValueSourceInternal.ThemeStyleTrigger || 
                                 valueSource == BaseValueSourceInternal.Style ||
                                 valueSource == BaseValueSourceInternal.TemplateTrigger || 
                                 valueSource == BaseValueSourceInternal.StyleTrigger || 
                                 valueSource == BaseValueSourceInternal.ParentTemplate ||
                                 valueSource == BaseValueSourceInternal.ParentTemplateTrigger); 
            }

            if (restoreMarker)
            { 
                newEntry.RestoreExpressionMarker();
            } 
            else if (oldEntry.IsExpression && oldEntry.ModifiedValue.ExpressionValue == Expression.NoValue) 
            {
                // we now have a value for an expression that is "hiding" - save it 
                // as the expression value
                newEntry.SetExpressionValue(newEntry.Value, oldEntry.ModifiedValue.BaseValue);
            }
 
#if DEBUG
            object baseValue; 
            if (!newEntry.HasModifiers) 
            {
                baseValue = newEntry.Value; 
            }
            else
            {
                if (newEntry.IsCoercedWithCurrentValue) 
                {
                    baseValue = newEntry.ModifiedValue.CoercedValue; 
                } 
                else if (newEntry.IsExpression)
                { 
                    baseValue = newEntry.ModifiedValue.ExpressionValue;
                }
                else
                { 
                    baseValue = newEntry.ModifiedValue.BaseValue;
                } 
            } 

            Debug.Assert(newEntry.IsDeferredReference == (baseValue is DeferredReference)); 
#endif

            if (entryIndex.Found)
            { 
                _effectiveValues[entryIndex.Index] = newEntry;
            } 
            else 
            {
                InsertEntry(newEntry, entryIndex.Index); 
                if (metadata != null && metadata.IsInherited)
                {
                    InheritableEffectiveValuesCount++;
                } 
            }
 
            Debug.Assert(dp == null || (dp.GlobalIndex == newEntry.PropertyIndex), "EffectiveValueEntry & DependencyProperty do not match"); 
        }
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        internal void GetRawValue(DependencyProperty dp, PropertyMetadata metadata, ref EffectiveValueEntry entry) 
        {
            // Check if value was resolved by base. If so, run it by animations
            if ((entry.BaseValueSourceInternal == BaseValueSourceInternal.Local) &&
                (entry.GetFlattenedEntry(RequestFlags.FullyResolved).Value != DependencyProperty.UnsetValue)) 
            {
                return; 
            } 

            // 
            // Try for container Style driven value
            //
            if (TemplateChildIndex != -1)
            { 
                // This instance is in the template child chain of a Template.VisualTree,
                //  so we need to see if the Style has an applicable value. 
                // 
                // If the parent element's style is changing, this instance is
                // in a visual tree that is being removed, and the value request 
                // is simply a result of tearing down some information in that
                // tree (e.g. a BindingExpression).  If so, just pretend there is no style (bug 991395).

                if (GetValueFromTemplatedParent(dp, ref entry)) 
                {
                    return; 
                } 
            }
 

            //
            // Try for Styled value
            // 

            // Here are some of the implicit rules used by GetRawValue, 
            // while querying properties on the container. 
            // 1. Style property cannot be specified in a Style
            // 2. Style property cannot be specified in a ThemeStyle 
            // 3. Style property cannot be specified in a Template
            // 4. DefaultStyleKey property cannot be specified in a ThemeStyle
            // 5. DefaultStyleKey property cannot be specified in a Template
            // 6. Template property cannot be specified in a Template 

            if (dp != StyleProperty) 
            { 
                if (StyleHelper.GetValueFromStyleOrTemplate(new FrameworkObject(null, this), dp, ref entry))
                { 
                    return;
                }
            }
            else 
            {
                object source; 
                object implicitValue = FrameworkElement.FindImplicitStyleResource(this, this.GetType(), out source); 
                if (implicitValue != DependencyProperty.UnsetValue)
                { 
                    // Commented this because the implicit fetch could also return a DeferredDictionaryReference
                    // if (!(implicitValue is Style))
                    // {
                    //     throw new InvalidOperationException(SR.Get(SRID.InvalidImplicitStyleResource, this.GetType().Name, implicitValue)); 
                    // }
 
                    // This style has been fetched from resources 
                    HasImplicitStyleFromResources = true;
 
                    entry.BaseValueSourceInternal = BaseValueSourceInternal.ImplicitReference;
                    entry.Value = implicitValue;
                    return;
                } 
            }
 
            // 
            // Try for Inherited value
            // 
            FrameworkPropertyMetadata fmetadata = metadata as FrameworkPropertyMetadata;

            // Note that for inheritable properties that override the default value a parent can impart
            // its default value to the child even though the property may not have been set locally or 
            // via a style or template (ie. IsUsed flag would be false).
            if (fmetadata != null) 
            { 
                if (fmetadata.Inherits)
                { 
                    //
                    // Inheritance
                    //
 
                    if (!TreeWalkHelper.SkipNext(InheritanceBehavior) || fmetadata.OverridesInheritanceBehavior == true)
                    { 
                        // Used to terminate tree walk if a tree boundary is hit 
                        InheritanceBehavior inheritanceBehavior;
 
                        FrameworkContentElement parentFCE;
                        FrameworkElement parentFE;
                        bool hasParent = FrameworkElement.GetFrameworkParent(this, out parentFE, out parentFCE);
                        while (hasParent) 
                        {
                            bool inheritanceNode; 
                            if (parentFE != null) 
                            {
                                inheritanceNode = TreeWalkHelper.IsInheritanceNode(parentFE, dp, out inheritanceBehavior); 
                            }
                            else // (parentFCE != null)
                            {
                                inheritanceNode = TreeWalkHelper.IsInheritanceNode(parentFCE, dp, out inheritanceBehavior); 
                            }
 
                            // If the current node has SkipNow semantics then we do 
                            // not need to lookup the inheritable value on it.
                            if (TreeWalkHelper.SkipNow(inheritanceBehavior)) 
                            {
                                break;
                            }
 
                            // Check if node is an inheritance node, if so, query it
                            if (inheritanceNode) 
                            { 
                                #region EventTracing
                                if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose)) 
                                {
                                    string TypeAndName = "[" + GetType().Name + "]" + dp.Name;
                                    EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientPropParentCheck,
                                                                         EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose, 
                                                                         GetHashCode(), TypeAndName);
                                } 
                                #endregion EventTracing 
                                DependencyObject parentDO = parentFE;
                                if (parentDO == null) 
                                {
                                    parentDO = parentFCE;
                                }
 
                                EntryIndex entryIndex = parentDO.LookupEntry(dp.GlobalIndex);
 
                                entry = parentDO.GetValueEntry( 
                                                entryIndex,
                                                dp, 
                                                fmetadata,
                                                RequestFlags.SkipDefault | RequestFlags.DeferredReferences);

                                if (entry.Value != DependencyProperty.UnsetValue) 
                                {
                                    entry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; 
                                } 
                                return;
                            } 

                            // If the current node has SkipNext semantics then we do
                            // not need to lookup the inheritable value on its parent.
                            if (TreeWalkHelper.SkipNext(inheritanceBehavior)) 
                            {
                                break; 
                            } 

                            // No boundary or inheritance node found, continue search 
                            if (parentFE != null)
                            {
                                hasParent = FrameworkElement.GetFrameworkParent(parentFE, out parentFE, out parentFCE);
                            } 
                            else
                            { 
                                hasParent = FrameworkElement.GetFrameworkParent(parentFCE, out parentFE, out parentFCE); 
                            }
                        } 
                    }
                }

 
            }
 
            // No value found. 
            Debug.Assert(entry.Value == DependencyProperty.UnsetValue);
        } 
Beispiel #35
0
        /// <summary>
        ///     The common code shared by all variants of SetValue 
        /// </summary> 
        // Takes metadata from caller because most of them have already retrieved it
        //  for their own purposes, avoiding the duplicate GetMetadata call. 
        private void SetValueCommon(
            DependencyProperty  dp,
            object              value,
            PropertyMetadata    metadata, 
            bool                coerceWithDeferredReference,
            bool                coerceWithCurrentValue, 
            OperationType       operationType, 
            bool                isInternal)
        { 
            if (IsSealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.SetOnReadOnlyObjectNotAllowed, this));
            } 

            Expression newExpr = null; 
            DependencySource[] newSources = null; 

            EntryIndex entryIndex = LookupEntry(dp.GlobalIndex); 

            // Treat Unset as a Clear
            if( value == DependencyProperty.UnsetValue )
            { 
                // Parameters should have already been validated, so we call
                //  into the private method to avoid validating again. 
                ClearValueCommon(entryIndex, dp, metadata); 
                return;
            } 

            // Validate the "value" against the DP.
            bool isDeferredReference = false;
            bool newValueHasExpressionMarker = (value == ExpressionInAlternativeStore); 

            // First try to validate the value; only after this validation fails should we 
            // do the more expensive checks (type checks) for the less common scenarios 
            if (!newValueHasExpressionMarker)
            { 
                bool isValidValue = isInternal ? dp.IsValidValueInternal(value) : dp.IsValidValue(value);

                // for properties of type "object", we have to always check for expression & deferredreference
                if (!isValidValue || dp.IsObjectType) 
                {
                    // 2nd most common is expression 
                    newExpr = value as Expression; 
                    if (newExpr != null)
                    { 
                        // For Expressions, perform additional validation
                        // Make sure Expression is "attachable"
                        if (!newExpr.Attachable)
                        { 
                            throw new ArgumentException(SR.Get(SRID.SharingNonSharableExpression));
                        } 
 
                        // Check dispatchers of all Sources
                        // CALLBACK 
                        newSources = newExpr.GetSources();
                        ValidateSources(this, newSources, newExpr);
                    }
                    else 
                    {
                        // and least common is DeferredReference 
                        isDeferredReference = (value is DeferredReference); 
                        if (!isDeferredReference)
                        { 
                            if (!isValidValue)
                            {
                                // it's not a valid value & it's not an expression, so throw
                                throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, value, dp.Name)); 
                            }
                        } 
                    } 
                }
            } 

            // Get old value
            EffectiveValueEntry oldEntry;
            if (operationType == OperationType.ChangeMutableDefaultValue) 
            {
                oldEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Default); 
                oldEntry.Value = value; 
            }
            else 
            {
                oldEntry = GetValueEntry(entryIndex, dp, metadata, RequestFlags.RawEntry);
            }
 
            // if there's an expression in some other store, fetch it now
            Expression currentExpr = 
                    (oldEntry.HasExpressionMarker)  ? _getExpressionCore(this, dp, metadata) 
                  : (oldEntry.IsExpression)         ? (oldEntry.LocalValue as Expression)
                  :                                   null; 

            // Allow expression to store value if new value is
            // not an Expression, if applicable
 
            bool handled = false;
            if ((currentExpr != null) && (newExpr == null)) 
            { 
                // Resolve deferred references because we haven't modified
                // the expression code to work with DeferredReference yet. 
                if (isDeferredReference)
                {
                    value = ((DeferredReference) value).GetValue(BaseValueSourceInternal.Local);
                } 

                // CALLBACK 
                handled = currentExpr.SetValue(this, dp, value); 
                entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);
            } 

            // Create the new effective value entry
            EffectiveValueEntry newEntry;
            if (handled) 
            {
                // If expression handled set, then done 
                if (entryIndex.Found) 
                {
                    newEntry = _effectiveValues[entryIndex.Index]; 
                }
                else
                {
                    // the expression.SetValue resulted in this value being removed from the table; 
                    // use the default value.
                    newEntry = EffectiveValueEntry.CreateDefaultValueEntry(dp, metadata.GetDefaultValue(this, dp)); 
                } 

                coerceWithCurrentValue = false; // expression already handled the control-value 
            }
            else
            {
                // allow a control-value to coerce an expression value, when the 
                // expression didn't handle the value
                if (coerceWithCurrentValue && currentExpr != null) 
                { 
                    currentExpr = null;
                } 

                newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Local);

                // detach the old expression, if applicable 
                if (currentExpr != null)
                { 
                    // CALLBACK 
                    DependencySource[] currentSources = currentExpr.GetSources();
 
                    UpdateSourceDependentLists(this, dp, currentSources, currentExpr, false);  // Remove

                    // CALLBACK
                    currentExpr.OnDetach(this, dp); 
                    currentExpr.MarkDetached();
                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex); 
                } 

                // attach the new expression, if applicable 
                if (newExpr == null)
                {
                    // simple local value set
                    newEntry.HasExpressionMarker = newValueHasExpressionMarker; 
                    newEntry.Value = value;
                } 
                else 
                {
                    Debug.Assert(!coerceWithCurrentValue, "Expression values not supported in SetCurrentValue"); 

                    // First put the expression in the effectivevalueentry table for this object;
                    // this allows the expression to update the value accordingly in OnAttach
                    SetEffectiveValue(entryIndex, dp, dp.GlobalIndex, metadata, newExpr, BaseValueSourceInternal.Local); 

                    // Before the expression is attached it has default value 
                    object defaultValue = metadata.GetDefaultValue(this, dp); 
                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);
                    SetExpressionValue(entryIndex, defaultValue, newExpr); 
                    UpdateSourceDependentLists(this, dp, newSources, newExpr, true);  // Add

                    newExpr.MarkAttached();
 
                    // CALLBACK
                    newExpr.OnAttach(this, dp); 
 
                    // the attach may have added entries in the effective value table ...
                    // so, update the entryIndex accordingly. 
                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);

                    newEntry = EvaluateExpression(
                            entryIndex, 
                            dp,
                            newExpr, 
                            metadata, 
                            oldEntry,
                            _effectiveValues[entryIndex.Index]); 

                    entryIndex = CheckEntryIndex(entryIndex, dp.GlobalIndex);
                }
            } 

            UpdateEffectiveValue( 
                entryIndex, 
                dp,
                metadata, 
                oldEntry,
                ref newEntry,
                coerceWithDeferredReference,
                coerceWithCurrentValue, 
                operationType);
        } 
        // This FrameworkElement has been established to be a Template.VisualTree
        //  node of a parent object.  Ask the TemplatedParent's Style object if
        //  they have a value for us. 

        private bool GetValueFromTemplatedParent(DependencyProperty dp, ref EffectiveValueEntry entry) 
        { 
            FrameworkTemplate frameworkTemplate = null;
            FrameworkElement feTemplatedParent = (FrameworkElement)_templatedParent; 
            frameworkTemplate = feTemplatedParent.TemplateInternal;

            if (frameworkTemplate != null)
            { 
                return StyleHelper.GetValueFromTemplatedParent(
                    _templatedParent, 
                    TemplateChildIndex, 
                    new FrameworkObject(null, this),
                    dp, 
                    ref frameworkTemplate.ChildRecordFromChildIndex,
                    frameworkTemplate.VisualTree,
                    ref entry);
            } 

            return false; 
        } 
Beispiel #37
0
        /// <summary> 
        ///     Invalidate this property if 
        ///     - It is not locally set and
        ///     - It is not acquired from a style/template 
        /// </summary>
        private static bool InvalidateTreeDependentProperty(
            TreeChangeInfo              info,
            DependencyObject            d, 
        ref FrameworkObject             fo,
            DependencyProperty          dp, 
            FrameworkPropertyMetadata   fMetadata, 
            Style                       selfStyle,
            Style                       selfThemeStyle, 
            ref ChildRecord             childRecord,
            bool                        isChildRecordValid,
            bool                        hasStyleChanged,
            bool                        isSelfInheritanceParent) 
        {
            Debug.Assert(d != null, "Must have non-null current node"); 
 
            // This must be an inherited dependency property
            Debug.Assert(fMetadata.IsInherited == true, "This must be an inherited dependency property"); 

            // Children do not need to inherit properties across a tree boundary
            // unless the property is set to override this behavior.
 
            if (!SkipNext(fo.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior)
            { 
                InheritablePropertyChangeInfo rootInfo = info.GetRootInheritableValue(dp); 

                EffectiveValueEntry oldEntry = rootInfo.OldEntry; 
                EffectiveValueEntry newEntry = info.IsAddOperation ? rootInfo.NewEntry : new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited);

                bool isForceInheritedProperty = IsForceInheritedProperty(dp);
 
                if (d != info.Root)
                { 
                    if (isSelfInheritanceParent) 
                    {
                        oldEntry = d.GetValueEntry( 
                                d.LookupEntry(dp.GlobalIndex),
                                dp,
                                fMetadata,
                                RequestFlags.DeferredReferences); 
                    }
                    else 
                    { 
                        oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                        oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; 
                    }
                }

                OperationType operationType = info.IsAddOperation ? OperationType.AddChild : OperationType.RemoveChild; 
                if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal)
                { 
                    // If the oldValueSource is of lower precedence than Inheritance 
                    // only then do we need to Invalidate the property. Examples of
                    // values with higher precedence are those that are locally set 
                    // or set via a style/template.
                    return (d.UpdateEffectiveValue(
                                d.LookupEntry(dp.GlobalIndex),
                                dp, 
                                fMetadata,
                                oldEntry, 
                                ref newEntry, 
                                false /* coerceWithDeferredReference */,
                                false /* coerceWithCurrentValue */, 
                                operationType)
                            & (UpdateResult.ValueChanged | UpdateResult.InheritedValueOverridden))
                            == UpdateResult.ValueChanged;
                        // return false if either the value didn't change or 
                        // it changed because the inherited value was overridden by coercion or animation.
                } 
                else if (isForceInheritedProperty) 
                {
                    // IsCoerced == true && value == UnsetValue indicates that we need to re-coerce this value 
                    newEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced);

                    // Re-coerce a force inherited property because it's coersion depends on treeness
                    return (d.UpdateEffectiveValue( 
                                d.LookupEntry(dp.GlobalIndex),
                                dp, 
                                fMetadata, 
                                oldEntry,
                                ref newEntry, 
                                false /* coerceWithDeferredReference */,
                                false /* coerceWithCurrentValue */,
                                operationType)
                            & (UpdateResult.ValueChanged | UpdateResult.InheritedValueOverridden)) 
                            == UpdateResult.ValueChanged;
                        // return false if either the value didn't change or 
                        // it changed because the inherited value was overridden by coercion or animation. 
                }
            } 

            return false;
        }
        // Like GetValueCore, except it returns the expression (if any) instead of its value
        internal Expression GetExpressionCore(DependencyProperty dp, PropertyMetadata metadata)
        {
            this.IsRequestingExpression = true; 
            EffectiveValueEntry entry = new EffectiveValueEntry(dp);
            entry.Value = DependencyProperty.UnsetValue; 
            this.EvaluateBaseValueCore(dp, metadata, ref entry); 
            this.IsRequestingExpression = false;
 
            return entry.Value as Expression;
        }
        //
        //  This method
        //  1. Is called from AncestorChange InvalidateTree.
        //  2. It is used to create the InheritableProperties on the given node.
        //  3. It also accumulates oldValues for the inheritable properties that are about to be invalidated
        //
        internal FrugalObjectList<DependencyProperty> CreateParentInheritableProperties(
            DependencyObject                         d,
            DependencyObject                         parent,
            bool                                     isAddOperation)
        {
            Debug.Assert(d != null, "Must have non-null current node");
            
            if (parent == null)
            {
                return new FrugalObjectList<DependencyProperty>(0);
            }

            DependencyObjectType treeObjDOT = d.DependencyObjectType;

            // See if we have a cached value.
            EffectiveValueEntry[] parentEffectiveValues = null;
            uint parentEffectiveValuesCount = 0;
            uint inheritablePropertiesCount = 0;

            // If inheritable properties aren't cached on you then use the effective
            // values cache on the parent to discover those inherited properties that
            // may need to be invalidated on the children nodes.
            if (!parent.IsSelfInheritanceParent)
            {
                DependencyObject inheritanceParent = parent.InheritanceParent;
                if (inheritanceParent != null)
                {
                    parentEffectiveValues = inheritanceParent.EffectiveValues;
                    parentEffectiveValuesCount = inheritanceParent.EffectiveValuesCount;
                    inheritablePropertiesCount = inheritanceParent.InheritableEffectiveValuesCount;
                }
            }
            else
            {
                parentEffectiveValues = parent.EffectiveValues;
                parentEffectiveValuesCount = parent.EffectiveValuesCount;
                inheritablePropertiesCount = parent.InheritableEffectiveValuesCount;
            }

            FrugalObjectList<DependencyProperty> inheritableProperties = new FrugalObjectList<DependencyProperty>((int) inheritablePropertiesCount);

            if (inheritablePropertiesCount == 0)
            {
                return inheritableProperties;
            }

            _rootInheritableValues = new InheritablePropertyChangeInfo[(int) inheritablePropertiesCount];
            int inheritableIndex = 0;

            FrameworkObject foParent = new FrameworkObject(parent);
            
            for (uint i=0; i<parentEffectiveValuesCount; i++)
            {
                // Add all the inheritable properties from the effectiveValues
                // cache to the TreeStateCache on the parent
                EffectiveValueEntry entry = parentEffectiveValues[i];
                DependencyProperty dp = DependencyProperty.RegisteredPropertyList.List[entry.PropertyIndex];

                // There are UncommonFields also stored in the EffectiveValues cache. We need to exclude those.
                if ((dp != null) && dp.IsPotentiallyInherited)
                {
                    PropertyMetadata metadata = dp.GetMetadata(parent.DependencyObjectType);
                    if (metadata != null && metadata.IsInherited)
                    {
                        Debug.Assert(!inheritableProperties.Contains(dp), "EffectiveValues cache must not contains duplicate entries for the same DP");

                        FrameworkPropertyMetadata fMetadata = (FrameworkPropertyMetadata)metadata;

                        // Children do not need to inherit properties across a tree boundary 
                        // unless the property is set to override this behavior.

                        if (!TreeWalkHelper.SkipNow(foParent.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior)
                        {
                            inheritableProperties.Add(dp);

                            EffectiveValueEntry oldEntry;
                            EffectiveValueEntry newEntry;

                            oldEntry = d.GetValueEntry(
                                        d.LookupEntry(dp.GlobalIndex),
                                        dp,
                                        dp.GetMetadata(treeObjDOT),
                                        RequestFlags.DeferredReferences);

                            if (isAddOperation)
                            {
                                // set up the new value
                                newEntry = entry;

                                if ((newEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default) || newEntry.HasModifiers)
                                {                        
                                    newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                                    newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
                                }                        
                            }
                            else
                            {
                                newEntry = new EffectiveValueEntry();
                            }

                            
                            _rootInheritableValues[inheritableIndex++] = 
                                        new InheritablePropertyChangeInfo(d, dp, oldEntry, newEntry);

                            if (inheritablePropertiesCount == inheritableIndex)
                            {
                                // no more inheritable properties, bail early
                                break;
                            }
                        }
                    }
                }
            }

            return inheritableProperties;
        }
        /// <summary>
        ///     Notification that a specified property has been changed 
        /// </summary> 
        /// <param name="e">EventArgs that contains the property, metadata, old value, and new value for this change</param>
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
        {
            DependencyProperty dp = e.Property;

            base.OnPropertyChanged(e); 

            if (e.IsAValueChange || e.IsASubPropertyChange) 
            { 
                //
                // Try to fire the Loaded event on the root of the tree 
                // because for this case the OnParentChanged will not
                // have a chance to fire the Loaded event.
                //
                if (dp != null && dp.OwnerType == typeof(PresentationSource) && dp.Name == "RootSource") 
                {
                    TryFireInitialized(); 
                } 

                if (dp == FrameworkElement.NameProperty && 
                    EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose))
                {
                    EventTrace.EventProvider.TraceEvent(EventTrace.Event.PerfElementIDName, EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose,
                            PerfService.GetPerfElementID(this), GetType().Name, GetValue(dp)); 
                }
 
                // 
                // Invalidation propagation for Styles
                // 

                // Regardless of metadata, the Style/DefaultStyleKey properties are never a trigger drivers
                if (dp != StyleProperty && dp != DefaultStyleKeyProperty)
                { 
                    // Note even properties on non-container nodes within a template could be driving a trigger
                    if (TemplatedParent != null) 
                    { 
                        FrameworkElement feTemplatedParent = TemplatedParent as FrameworkElement;
 
                        FrameworkTemplate frameworkTemplate = feTemplatedParent.TemplateInternal;
                        StyleHelper.OnTriggerSourcePropertyInvalidated(null, frameworkTemplate, TemplatedParent, dp, e, false /*invalidateOnlyContainer*/,
                            ref frameworkTemplate.TriggerSourceRecordFromChildIndex, ref frameworkTemplate.PropertyTriggersWithActions, TemplateChildIndex /*sourceChildIndex*/);
                    } 

                    // Do not validate Style during an invalidation if the Style was 
                    // never used before (dependents do not need invalidation) 
                    if (Style != null)
                    { 
                        StyleHelper.OnTriggerSourcePropertyInvalidated(Style, null, this, dp, e, true /*invalidateOnlyContainer*/,
                            ref Style.TriggerSourceRecordFromChildIndex, ref Style.PropertyTriggersWithActions, 0 /*sourceChildId*/); // Style can only have triggers that are driven by properties on the container
                    }
 
                    // Do not validate Template during an invalidation if the Template was
                    // never used before (dependents do not need invalidation) 
 
                    // There may be container dependents in the ThemeStyle. Invalidate them.
                    if (ThemeStyle != null && Style != ThemeStyle) 
                    {
                        StyleHelper.OnTriggerSourcePropertyInvalidated(ThemeStyle, null, this, dp, e, true /*invalidateOnlyContainer*/,
                            ref ThemeStyle.TriggerSourceRecordFromChildIndex, ref ThemeStyle.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // ThemeStyle can only have triggers that are driven by properties on the container
                    } 
                }
            } 
 
            FrameworkPropertyMetadata fmetadata = e.Metadata as FrameworkPropertyMetadata;
 
            //
            // Invalidation propagation for Groups and Inheritance
            //
 
            // Metadata must exist specifically stating propagate invalidation
            // due to group or inheritance 
            if (fmetadata != null) 
            {
                // 
                // Inheritance
                //

                if (fmetadata.Inherits) 
                {
                    // Invalidate Inheritable descendents only if instance is not a TreeSeparator 
                    // or fmetadata.OverridesInheritanceBehavior is set to override separated tree behavior 
                    if ((InheritanceBehavior == InheritanceBehavior.Default || fmetadata.OverridesInheritanceBehavior) &&
                        (!DependencyObject.IsTreeWalkOperation(e.OperationType) || PotentiallyHasMentees)) 
                    {
                        EffectiveValueEntry newEntry = e.NewEntry;
                        EffectiveValueEntry oldEntry = e.OldEntry;
                        if (oldEntry.BaseValueSourceInternal > newEntry.BaseValueSourceInternal) 
                        {
                            // valuesource == Inherited && value == UnsetValue indicates that we are clearing the inherited value 
                            newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited); 
                        }
                        else 
                        {
                            newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                            newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
                        } 

                        if (oldEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default || oldEntry.HasModifiers) 
                        { 
                            oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
                            oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; 
                        }
                        else
                        {
                            // we use an empty EffectiveValueEntry as a signal that the old entry was the default value 
                            oldEntry = new EffectiveValueEntry();
                        } 
 
                        InheritablePropertyChangeInfo info =
                                new InheritablePropertyChangeInfo( 
                                        dp,
                                        oldEntry,
                                        newEntry);
 
                        // Don't InvalidateTree if we're in the middle of doing it.
                        if (!DependencyObject.IsTreeWalkOperation(e.OperationType)) 
                        { 
                            TreeWalkHelper.InvalidateOnInheritablePropertyChange(null, this, info, true);
                        } 

                        // Notify mentees if they exist
                        if (PotentiallyHasMentees)
                        { 
                            TreeWalkHelper.OnInheritedPropertyChanged(this, ref info, InheritanceBehavior);
                        } 
                    } 
                }
            } 
        }