Example #1
0
        private void SetCacheFlagInAncestry(DependencyObject element,
                                            bool newValue,
                                            DeferredElementTreeState treeState,
                                            bool shortCircuit,
                                            bool setOriginCacheFlag)
        {
            UIElement      uie;
            ContentElement ce;
            UIElement3D    uie3D;

            CastElement(element, out uie, out ce, out uie3D);

            bool isFlagSet            = IsFlagSet(uie, ce, uie3D, FlagCache);
            bool isFlagOriginCacheSet = (setOriginCacheFlag ? IsFlagSet(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache)) : false);

            // If the cache flag value is undergoing change, record it and
            // propagate the change to the ancestors.
            if ((newValue != isFlagSet) ||
                (setOriginCacheFlag && !isFlagOriginCacheSet) ||
                !shortCircuit)
            {
                if (newValue != isFlagSet)
                {
                    SetFlag(uie, ce, uie3D, FlagCache, newValue);

                    // NOTE: we toggle the changed flag instead of setting it so that that way common
                    // ancestors show resultant unchanged and do not receive any change notification.
                    SetFlag(uie, ce, uie3D, FlagChanged, !IsFlagSet(uie, ce, uie3D, FlagChanged));
                }

                if (setOriginCacheFlag && !isFlagOriginCacheSet)
                {
                    SetFlag(uie, ce, uie3D, (newValue ? FlagNewOriginCache : FlagOldOriginCache), true);
                }

                // Check for block reverse inheritance flag, elements like popup want to set this.
                if (BlockReverseInheritance(uie, ce, uie3D))
                {
                    return;
                }

                // Propagate the flag up the visual and logical trees.  Note our
                // minimal optimization check to avoid walking both the core
                // and logical parents if they are the same.
                {
                    DependencyObject coreParent    = DeferredElementTreeState.GetInputElementParent(element, treeState);
                    DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState);

                    if (coreParent != null)
                    {
                        SetCacheFlagInAncestry(coreParent, newValue, treeState, shortCircuit, setOriginCacheFlag);
                    }
                    if (logicalParent != null && logicalParent != coreParent)
                    {
                        SetCacheFlagInAncestry(logicalParent, newValue, treeState, shortCircuit, setOriginCacheFlag);
                    }
                }
            }
        }
Example #2
0
        private void FirePropertyChangeInAncestry(DependencyObject element,
                                                  bool oldValue,
                                                  DeferredElementTreeState treeState,
                                                  Action <DependencyObject, bool> originChangedAction)
        {
            UIElement      uie;
            ContentElement ce;
            UIElement3D    uie3D;

            CastElement(element, out uie, out ce, out uie3D);

            bool flagChanged             = IsFlagSet(uie, ce, uie3D, FlagChanged);
            bool isFlagOldOriginCacheSet = ((FlagOldOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagOldOriginCache));
            bool isFlagNewOriginCacheSet = ((FlagNewOriginCache == CoreFlags.None) ? false : IsFlagSet(uie, ce, uie3D, FlagNewOriginCache));

            if (flagChanged || isFlagOldOriginCacheSet || isFlagNewOriginCacheSet)
            {
                if (flagChanged)
                {
                    // if FlagChanged bit is set, then the value has changed effectively
                    // after considering all the origins. Hence change the property value
                    // and fire notifications.
                    SetFlag(uie, ce, uie3D, FlagChanged, false);

                    if (oldValue)
                    {
                        element.ClearValue(FlagKey);
                    }
                    else
                    {
                        element.SetValue(FlagKey, true);
                    }

                    FireNotifications(uie, ce, uie3D, oldValue);
                }

                if (isFlagOldOriginCacheSet || isFlagNewOriginCacheSet)
                {
                    SetFlag(uie, ce, uie3D, FlagOldOriginCache, false);
                    SetFlag(uie, ce, uie3D, FlagNewOriginCache, false);
                    if (isFlagOldOriginCacheSet != isFlagNewOriginCacheSet)
                    {
                        // if either FlagOldOriginCache or FlagNewOriginCache
                        // are set, then the origin change has affected this node
                        // and hence originChangedAction should be executed.
                        Debug.Assert(originChangedAction != null);
                        originChangedAction(element, oldValue);
                    }
                }

                // Check for block reverse inheritance flag, elements like popup want to set this.
                if (BlockReverseInheritance(uie, ce, uie3D))
                {
                    return;
                }

                // Call FirePropertyChange up the visual and logical trees.
                // Note our minimal optimization check to avoid walking both
                // the core and logical parents if they are the same.
                {
                    DependencyObject coreParent    = DeferredElementTreeState.GetInputElementParent(element, treeState);
                    DependencyObject logicalParent = DeferredElementTreeState.GetLogicalParent(element, treeState);

                    if (coreParent != null)
                    {
                        FirePropertyChangeInAncestry(coreParent, oldValue, treeState, originChangedAction);
                    }
                    if (logicalParent != null && logicalParent != coreParent)
                    {
                        FirePropertyChangeInAncestry(logicalParent, oldValue, treeState, originChangedAction);
                    }
                }
            }
        }