ReverseInheritProperty.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / ReverseInheritProperty.cs / 1305600 / ReverseInheritProperty.cs

                            using System; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Media;
using System.Windows.Input; 
using MS.Internal;
 
namespace System.Windows 
{
    internal abstract class ReverseInheritProperty 
    {
        internal ReverseInheritProperty(
            DependencyPropertyKey flagKey,
            CoreFlags flagCache, 
            CoreFlags flagChanged)
            : this(flagKey, flagCache, flagChanged, CoreFlags.None, CoreFlags.None) 
        { 
        }
 
        internal ReverseInheritProperty(
            DependencyPropertyKey flagKey,
            CoreFlags flagCache,
            CoreFlags flagChanged, 
            CoreFlags flagOldOriginCache,
            CoreFlags flagNewOriginCache) 
        { 
            FlagKey = flagKey;
            FlagCache = flagCache; 
            FlagChanged = flagChanged;
            FlagOldOriginCache = flagOldOriginCache;
            FlagNewOriginCache = flagNewOriginCache;
        } 

        internal abstract void FireNotifications(UIElement uie, ContentElement ce, UIElement3D uie3D, bool oldValue); 
 
        internal void OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, ref DeferredElementTreeState oldTreeState)
        { 
            OnOriginValueChanged(oldOrigin, newOrigin, null, ref oldTreeState, null);
        }

        internal void OnOriginValueChanged(DependencyObject oldOrigin, 
            DependencyObject newOrigin,
            IList otherOrigins, 
            ref DeferredElementTreeState oldTreeState, 
            Action originChangedAction)
        { 
            DeferredElementTreeState treeStateLocalCopy = oldTreeState;
            oldTreeState = null;

            // Determine if one needs to raise notifications of elements 
            // affected by the origin change irrespective of other origins
            bool setOriginCacheFlag = ((originChangedAction != null) && 
                                       (FlagOldOriginCache != CoreFlags.None) && 
                                       (FlagNewOriginCache != CoreFlags.None));
 
            // Step #1
            // Update the cache flags for all elements in the ancestry
            // of the element that got turned off and record the changed nodes
            if (oldOrigin != null) 
            {
                SetCacheFlagInAncestry(oldOrigin, false, treeStateLocalCopy, true, setOriginCacheFlag); 
            } 

            // Step #2 
            // Update the cache flags for all elements in the ancestry
            // of the element that got turned on and record the changed nodes
            if (newOrigin != null)
            { 
                SetCacheFlagInAncestry(newOrigin, true, null, true, setOriginCacheFlag);
            } 
            int otherCount = (otherOrigins != null) ? otherOrigins.Count : 0; 
            for (int i = 0; i < otherCount; i++)
            { 
                // setOriginCacheFlag is false, because these flags should not be affected by other origins
                SetCacheFlagInAncestry(otherOrigins[i], true, null, false, /*setOriginCacheFlag*/ false);
            }
 
            // Step #3
            // Fire value changed on elements in the ancestry of the element that got turned off. 
            if (oldOrigin != null) 
            {
                FirePropertyChangeInAncestry(oldOrigin, true /* oldValue */, treeStateLocalCopy, originChangedAction); 
            }

            // Step #4
            // Fire value changed on elements in the ancestry of the element that got turned on. 
            if (newOrigin != null)
            { 
                FirePropertyChangeInAncestry(newOrigin, false /* oldValue */, null, originChangedAction); 
            }
 
            if (oldTreeState == null && treeStateLocalCopy != null)
            {
                // Now that we have applied the old tree state, throw it away.
                treeStateLocalCopy.Clear(); 
                oldTreeState = treeStateLocalCopy;
            } 
        } 

        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 isFla----ginCacheSet = (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 && !isFla----ginCacheSet) ||
                !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 && !isFla----ginCacheSet)
                {
                    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);
                    } 
                }
            }
        }
 
        private void FirePropertyChangeInAncestry(DependencyObject element,
            bool oldValue, 
            DeferredElementTreeState treeState, 
            Action 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);
                    }
                }
            } 
        }
 
        ///////////////////////////////////////////////////////////////////// 

        private static bool BlockReverseInheritance(UIElement uie, ContentElement ce, UIElement3D uie3D) 
        {
            if (uie != null)
            {
                return uie.BlockReverseInheritance(); 
            }
            else if (ce != null) 
            { 
                return ce.BlockReverseInheritance();
            } 
            else if (uie3D != null)
            {
                return uie3D.BlockReverseInheritance();
            } 

            return false; 
        } 

        ///////////////////////////////////////////////////////////////////// 

        private static void SetFlag(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag, bool value)
        {
            if (uie != null) 
            {
                uie.WriteFlag(flag, value); 
            } 
            else if (ce != null)
            { 
                ce.WriteFlag(flag, value);
            }
            else if (uie3D != null)
            { 
                uie3D.WriteFlag(flag, value);
            } 
        } 

        ///////////////////////////////////////////////////////////////////// 

        private static bool IsFlagSet(UIElement uie, ContentElement ce, UIElement3D uie3D, CoreFlags flag)
        {
            if (uie != null) 
            {
                return uie.ReadFlag(flag); 
            } 
            else if (ce != null)
            { 
                return ce.ReadFlag(flag);
            }
            else if (uie3D != null)
            { 
                return uie3D.ReadFlag(flag);
            } 
 
            return false;
        } 

        /////////////////////////////////////////////////////////////////////

        private static void CastElement(DependencyObject o, out UIElement uie, out ContentElement ce, out UIElement3D uie3D) 
        {
            uie = o as UIElement; 
            ce = (uie != null) ? null : o as ContentElement; 
            uie3D = (uie != null || ce != null) ? null : o as UIElement3D;
        } 

        /////////////////////////////////////////////////////////////////////

        protected DependencyPropertyKey FlagKey; 
        protected CoreFlags FlagCache;
        protected CoreFlags FlagChanged; 
        protected CoreFlags FlagOldOriginCache; // Flag to keep track of elements in the path of old origin 
        protected CoreFlags FlagNewOriginCache; // Flag to keep track of elements in the path of new origin
    } 
}


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

Link Menu

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