Exemple #1
0
 // Token: 0x06000C6E RID: 3182 RVA: 0x0002ECD4 File Offset: 0x0002CED4
 internal static void OnInheritedPropertyChanged(DependencyObject d, ref InheritablePropertyChangeInfo info, InheritanceBehavior inheritanceBehavior)
 {
     if (inheritanceBehavior == InheritanceBehavior.Default || TreeWalkHelper.IsForceInheritedProperty(info.Property))
     {
         FrameworkObject frameworkObject = new FrameworkObject(d);
         frameworkObject.OnInheritedPropertyChanged(ref info);
     }
 }
Exemple #2
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);
 }
Exemple #3
0
        // Helper method to retrieve and fire the InheritedPropertyChanged event
        internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info)
        {
            EventHandlersStore store = EventHandlersStore;

            if (store != null)
            {
                Delegate handler = store.Get(FrameworkElement.InheritedPropertyChangedKey);
                if (handler != null)
                {
                    InheritedPropertyChangedEventArgs args = new InheritedPropertyChangedEventArgs(ref info);
                    ((InheritedPropertyChangedEventHandler)handler)(this, args);
                }
            }
        }
Exemple #4
0
 // raise the InheritedPropertyChanged event to mentees.  Called from FE/FCE
 // OnPropertyChanged
 internal static void OnInheritedPropertyChanged(DependencyObject d, 
                                     ref InheritablePropertyChangeInfo info,
                                     InheritanceBehavior inheritanceBehavior) 
 { 
     if (inheritanceBehavior == InheritanceBehavior.Default || IsForceInheritedProperty(info.Property))
     { 
         FrameworkObject fo = new FrameworkObject(d);
         fo.OnInheritedPropertyChanged(ref info);
     }
 } 
Exemple #5
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);
        } 
Exemple #6
0
        /// <summary>
        /// </summary> 
        internal static void InvalidateOnInheritablePropertyChange(
            FrameworkElement              fe, 
            FrameworkContentElement       fce, 
            InheritablePropertyChangeInfo info,
            bool                          skipStartNode) 
        {
            DependencyProperty dp = info.Property;
            FrameworkObject fo = new FrameworkObject(fe, fce);
            Debug.Assert(fo.IsValid, "Node with the resources change notification must be an FE or an FCE."); 

            if (HasChildren(fe, fce)) 
            { 
                // Spin up a DescendentsWalker only when
                // the current node has children to walk 

                DependencyObject d = fo.DO;

                DescendentsWalker<InheritablePropertyChangeInfo> walker = new DescendentsWalker<InheritablePropertyChangeInfo>( 
                    TreeWalkPriority.LogicalTree, InheritablePropertyChangeDelegate, info);
 
                walker.StartWalk(d, skipStartNode); 
            }
            else if (!skipStartNode) 
            {
                // Degenerate case when the current node is a leaf node and has no children.
                // If the current node needs a notification, do so now.
                OnInheritablePropertyChanged(fo.DO, info); 
            }
        } 
 internal void OnInheritedPropertyChanged(ref InheritablePropertyChangeInfo info)
 {
     if (IsFE)
     {
         _fe.RaiseInheritedPropertyChangedEvent(ref info);
     }
     else if (IsFCE)
     {
         _fce.RaiseInheritedPropertyChangedEvent(ref info);
     }
 }
        /// <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);
                        } 
                    } 
                }
            } 
        }
 // Helper method to retrieve and fire the InheritedPropertyChanged event
 internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info)
 {
     EventHandlersStore store = EventHandlersStore;
     if (store != null)
     {
         Delegate handler = store.Get(FrameworkElement.InheritedPropertyChangedKey);
         if (handler != null)
         {
             InheritedPropertyChangedEventArgs args = new InheritedPropertyChangedEventArgs(ref info);
             ((InheritedPropertyChangedEventHandler)handler)(this, args);
         }
     }
 }
Exemple #10
0
        // Token: 0x06000C6C RID: 3180 RVA: 0x0002EB1C File Offset: 0x0002CD1C
        internal static void InvalidateOnInheritablePropertyChange(FrameworkElement fe, FrameworkContentElement fce, InheritablePropertyChangeInfo info, bool skipStartNode)
        {
            DependencyProperty property        = info.Property;
            FrameworkObject    frameworkObject = new FrameworkObject(fe, fce);

            if (TreeWalkHelper.HasChildren(fe, fce))
            {
                DependencyObject @do = frameworkObject.DO;
                DescendentsWalker <InheritablePropertyChangeInfo> descendentsWalker = new DescendentsWalker <InheritablePropertyChangeInfo>(TreeWalkPriority.LogicalTree, TreeWalkHelper.InheritablePropertyChangeDelegate, info);
                descendentsWalker.StartWalk(@do, skipStartNode);
                return;
            }
            if (!skipStartNode)
            {
                bool visitedViaVisualTree = false;
                TreeWalkHelper.OnInheritablePropertyChanged(frameworkObject.DO, info, visitedViaVisualTree);
            }
        }
        //
        //  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/Template/DefaultStyleKey properties are never a trigger drivers
                if (dp != StyleProperty && dp != Control.TemplateProperty && 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 /*sourceChildIndex*/); // 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) 
                    if (TemplateInternal != null)
                    { 
                        StyleHelper.OnTriggerSourcePropertyInvalidated(null, TemplateInternal, this, dp, e, !HasTemplateGeneratedSubTree /*invalidateOnlyContainer*/,
                            ref TemplateInternal.TriggerSourceRecordFromChildIndex, ref TemplateInternal.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // These are driven by the container
                    }
 
                    // 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(this, null, info, true);
                        } 
 
                        // Notify mentees if they exist
                        if (PotentiallyHasMentees) 
                        {
                            TreeWalkHelper.OnInheritedPropertyChanged(this, ref info, InheritanceBehavior);
                        }
                    } 
                }
 
                if (e.IsAValueChange || e.IsASubPropertyChange) 
                {
                    // 
                    // Layout invalidation
                    //

                    // Skip if we're traversing an Visibility=Collapsed subtree while 
                    //  in the middle of an invalidation storm due to ancestor change
                    if( !(AncestorChangeInProgress && InVisibilityCollapsedTree) ) 
                    { 
                        UIElement layoutParent = null;
 
                        bool affectsParentMeasure = fmetadata.AffectsParentMeasure;
                        bool affectsParentArrange = fmetadata.AffectsParentArrange;
                        bool affectsMeasure = fmetadata.AffectsMeasure;
                        bool affectsArrange = fmetadata.AffectsArrange; 
                        if (affectsMeasure || affectsArrange || affectsParentArrange || affectsParentMeasure)
                        { 
                            // Locate nearest Layout parent 
                            for (Visual v = VisualTreeHelper.GetParent(this) as Visual;
                                 v != null; 
                                 v = VisualTreeHelper.GetParent(v) as Visual)
                            {
                                layoutParent = v as UIElement;
                                if (layoutParent != null) 
                                {
                                    //let incrementally-updating FrameworkElements to mark the vicinity of the affected child 
                                    //to perform partial update. 
                                    if(FrameworkElement.DType.IsInstanceOfType(layoutParent))
                                        ((FrameworkElement)layoutParent).ParentLayoutInvalidated(this); 

                                    if (affectsParentMeasure)
                                    {
                                        layoutParent.InvalidateMeasure(); 
                                    }
 
                                    if (affectsParentArrange) 
                                    {
                                        layoutParent.InvalidateArrange(); 
                                    }

                                    break;
                                } 
                            }
                        } 
 
                        if (fmetadata.AffectsMeasure)
                        { 
                            //


 
                            if (!BypassLayoutPolicies || !((dp == WidthProperty) || (dp == HeightProperty)))
                            { 
                                InvalidateMeasure(); 
                            }
                        } 

                        if (fmetadata.AffectsArrange)
                        {
                            InvalidateArrange(); 
                        }
 
                        if (fmetadata.AffectsRender && 
                            (e.IsAValueChange || !fmetadata.SubPropertiesDoNotAffectRender))
                        { 
                            InvalidateVisual();
                        }
                    }
                } 
            }
        } 
 internal InheritedPropertyChangedEventArgs(ref InheritablePropertyChangeInfo info) 
 {
     _info = info;
 }
 protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
 {
     DependencyProperty property = e.Property;
       base.OnPropertyChanged(e);
       if (e.IsAValueChange || e.IsASubPropertyChange)
       {
     if (property != null && property.OwnerType == typeof (PresentationSource) && property.Name == "RootSource")
       this.TryFireInitialized();
     if (property == FrameworkElement.NameProperty && EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose))
     {
       int num = (int) EventTrace.EventProvider.TraceEvent(EventTrace.Event.PerfElementIDName, EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose, (object) PerfService.GetPerfElementID((object) this), (object) this.GetType().Name, this.GetValue(property));
     }
     if (property != FrameworkElement.StyleProperty && property != Control.TemplateProperty && property != FrameworkElement.DefaultStyleKeyProperty)
     {
       if (this.TemplatedParent != null)
       {
     FrameworkTemplate templateInternal = (this.TemplatedParent as FrameworkElement).TemplateInternal;
     StyleHelper.OnTriggerSourcePropertyInvalidated((Style) null, templateInternal, this.TemplatedParent, property, e, false, ref templateInternal.TriggerSourceRecordFromChildIndex, ref templateInternal.PropertyTriggersWithActions, this.TemplateChildIndex);
       }
       if (this.Style != null)
     StyleHelper.OnTriggerSourcePropertyInvalidated(this.Style, (FrameworkTemplate) null, (DependencyObject) this, property, e, true, ref this.Style.TriggerSourceRecordFromChildIndex, ref this.Style.PropertyTriggersWithActions, 0);
       if (this.TemplateInternal != null)
     StyleHelper.OnTriggerSourcePropertyInvalidated((Style) null, this.TemplateInternal, (DependencyObject) this, property, e, !this.HasTemplateGeneratedSubTree, ref this.TemplateInternal.TriggerSourceRecordFromChildIndex, ref this.TemplateInternal.PropertyTriggersWithActions, 0);
       if (this.ThemeStyle != null && this.Style != this.ThemeStyle)
     StyleHelper.OnTriggerSourcePropertyInvalidated(this.ThemeStyle, (FrameworkTemplate) null, (DependencyObject) this, property, e, true, ref this.ThemeStyle.TriggerSourceRecordFromChildIndex, ref this.ThemeStyle.PropertyTriggersWithActions, 0);
     }
       }
       FrameworkPropertyMetadata propertyMetadata = e.Metadata as FrameworkPropertyMetadata;
       if (propertyMetadata == null)
     return;
       if (propertyMetadata.Inherits && (this.InheritanceBehavior == InheritanceBehavior.Default || propertyMetadata.OverridesInheritanceBehavior) && (!DependencyObject.IsTreeWalkOperation(e.OperationType) || this.PotentiallyHasMentees))
       {
     EffectiveValueEntry newEntry = e.NewEntry;
     EffectiveValueEntry oldEntry1 = e.OldEntry;
     if (oldEntry1.BaseValueSourceInternal > newEntry.BaseValueSourceInternal)
     {
       newEntry = new EffectiveValueEntry(property, BaseValueSourceInternal.Inherited);
     }
     else
     {
       newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved);
       newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
     }
     EffectiveValueEntry oldEntry2;
     if (oldEntry1.BaseValueSourceInternal != BaseValueSourceInternal.Default || oldEntry1.HasModifiers)
     {
       oldEntry2 = oldEntry1.GetFlattenedEntry(RequestFlags.FullyResolved);
       oldEntry2.BaseValueSourceInternal = BaseValueSourceInternal.Inherited;
     }
     else
       oldEntry2 = new EffectiveValueEntry();
     InheritablePropertyChangeInfo info = new InheritablePropertyChangeInfo((DependencyObject) this, property, oldEntry2, newEntry);
     if (!DependencyObject.IsTreeWalkOperation(e.OperationType))
       TreeWalkHelper.InvalidateOnInheritablePropertyChange(this, (FrameworkContentElement) null, info, true);
     if (this.PotentiallyHasMentees)
       TreeWalkHelper.OnInheritedPropertyChanged((DependencyObject) this, ref info, this.InheritanceBehavior);
       }
       if (!e.IsAValueChange && !e.IsASubPropertyChange || this.AncestorChangeInProgress && this.InVisibilityCollapsedTree)
     return;
       bool affectsParentMeasure = propertyMetadata.AffectsParentMeasure;
       bool affectsParentArrange = propertyMetadata.AffectsParentArrange;
       if (propertyMetadata.AffectsMeasure || propertyMetadata.AffectsArrange || (affectsParentArrange || affectsParentMeasure))
       {
     for (Visual visual = VisualTreeHelper.GetParent((DependencyObject) this) as Visual; visual != null; visual = VisualTreeHelper.GetParent((DependencyObject) visual) as Visual)
     {
       UIElement uiElement = visual as UIElement;
       if (uiElement != null)
       {
     if (FrameworkElement.DType.IsInstanceOfType((DependencyObject) uiElement))
       ((FrameworkElement) uiElement).ParentLayoutInvalidated((UIElement) this);
     if (affectsParentMeasure)
       uiElement.InvalidateMeasure();
     if (affectsParentArrange)
     {
       uiElement.InvalidateArrange();
       break;
     }
     else
       break;
       }
     }
       }
       if (propertyMetadata.AffectsMeasure && (!this.BypassLayoutPolicies || property != FrameworkElement.WidthProperty && property != FrameworkElement.HeightProperty))
     this.InvalidateMeasure();
       if (propertyMetadata.AffectsArrange)
     this.InvalidateArrange();
       if (!propertyMetadata.AffectsRender || !e.IsAValueChange && propertyMetadata.SubPropertiesDoNotAffectRender)
     return;
       this.InvalidateVisual();
 }
 internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info)
 {
     EventHandlersStore eventHandlersStore = this.EventHandlersStore;
       if (eventHandlersStore == null)
     return;
       Delegate @delegate = eventHandlersStore.Get(FrameworkElement.InheritedPropertyChangedKey);
       if (@delegate == null)
     return;
       InheritedPropertyChangedEventArgs e = new InheritedPropertyChangedEventArgs(ref info);
       ((InheritedPropertyChangedEventHandler) @delegate)((object) this, e);
 }
        //
        //  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;
        }
Exemple #17
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);
        }
Exemple #18
0
        /// <summary>
        ///     Callback on visiting each node in the descendency
        ///     during an inheritable property change
        /// </summary>
        private static bool OnInheritablePropertyChanged(
            DependencyObject              d,
            InheritablePropertyChangeInfo info,
            bool                          visitedViaVisualTree)
        {
            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)
                {
                    if (visitedViaVisualTree && FrameworkElement.DType.IsInstanceOfType(d))
                    {
                        DependencyObject logicalParent = LogicalTreeHelper.GetParent(d);
                        if (logicalParent != null)
                        {
                            DependencyObject visualParent = VisualTreeHelper.GetParent(d);
                            if (visualParent != null && visualParent != logicalParent)
                            {
                                // Consider the following logical tree configuration. In this case we want 
                                // to RibbonToggleButton to pick up the new DataContext flowing in from 
                                // the Window.
                                //
                                // Window (info.RootElement)
                                //   ...
                                //   RibbonGroup (IsCollapsed)
                                //      RibbonControl (only in visual tree)
                                //          RibbonToggleButton
                                //
                                // Consider the following logical tree configuration. In this case we do not 
                                // want to RibbonToggleButton to change its DataContext because the changes 
                                // are only within the visual tree.
                                //
                                // Window 
                                //   ...
                                //   RibbonGroup (IsCollapsed)
                                //      RibbonControl (only in visual tree) (info.RootElement)
                                //          RibbonToggleButton
                                //
                                // Saying it another way, the RibbonToggleButton in the above case belongs in a 
                                // different logical tree than the one that the current invalidation storm begun.
                                //
                                // Any change in an inheritable property begins an invalidation storm using the 
                                // DescendentsWalker and configures it to first traverse the logical children 
                                // and then visual children. Also nodes that have previously been visited via the 
                                // logical tree do not get visited again through the visual tree. I use this very 
                                // behavior as the basis for detecting nodes such as RibbonToggleButton. If the 
                                // RibbonToggleButton is being visisted for the first time via the visual tree then 
                                // the invalidation storm did not include its logical parent. And therefore the 
                                // RibbonToggleButton can early out of this storm.
                                return false;
                            }
                        }
                    }
                    
                    // 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);
        }