FrameworkContentElement.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 / Framework / System / Windows / Generated / FrameworkContentElement.cs / 1305600 / FrameworkContentElement.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// This file was generated, please do not edit it directly. 
// 
// This file was generated from the codegen template located at:
//     wpf\src\Graphics\codegen\mcg\generators\FrameworkElementTemplate.cs 
//
// Please see http://wiki/default.aspx/Microsoft.Projects.Avalon/MilCodeGen.html for more information.
//
//--------------------------------------------------------------------------- 

using MS.Internal; 
using MS.Utility; 

using System; 
using System.Collections;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions; 
using System.Windows.Controls;
using System.Windows.Media; 
using System.Windows.Markup; 

using SR=System.Windows.SR; 
using SRID=System.Windows.SRID;

namespace System.Windows
{ 
    [RuntimeNamePropertyAttribute("Name")]
    public partial class FrameworkContentElement 
    { 
        //-----------------------------------------------------
        // 
        //  Constructors
        //
        //-----------------------------------------------------
 
        //------------------------------------------------------
        // 
        //  Public Methods 
        //
        //----------------------------------------------------- 

        #region Public Methods

 
        /// 
        ///     Returns logical parent 
        ///  
        public new DependencyObject Parent
        { 
            get
            {
                // Verify Context Access
                // VerifyAccess(); 

                return ContextVerifiedGetParent(); 
            } 
        }
 
        /// 
        /// Registers the name - element combination from the
        /// NameScope that the current element belongs to.
        ///  
        /// Name of the element
        /// Element where name is defined 
        public void RegisterName(string name, object scopedElement) 
        {
            INameScope nameScope = FrameworkElement.FindScope(this); 
            if (nameScope != null)
            {
                nameScope.RegisterName(name, scopedElement);
            } 
            else
            { 
                throw new InvalidOperationException(SR.Get(SRID.NameScopeNotFound, name, "register")); 
            }
        } 

        /// 
        /// Unregisters the name - element combination from the
        /// NameScope that the current element belongs to. 
        /// 
        /// Name of the element 
        public void UnregisterName(string name) 
        {
            INameScope nameScope = FrameworkElement.FindScope(this); 
            if (nameScope != null)
            {
                nameScope.UnregisterName(name);
            } 
            else
            { 
                throw new InvalidOperationException(SR.Get(SRID.NameScopeNotFound, name, "unregister")); 
            }
        } 

        /// 
        /// Find the object with given name in the
        /// NameScope that the current element belongs to. 
        /// 
        /// string name to index 
        /// context if found, else null 
        public object FindName(string name)
        { 
            DependencyObject scopeOwner;
            return FindName(name, out scopeOwner);
        }
 
        // internal version of FindName that returns the scope owner
        internal object FindName(string name, out DependencyObject scopeOwner) 
        { 
            INameScope nameScope = FrameworkElement.FindScope(this, out scopeOwner);
            if (nameScope != null) 
            {
                return nameScope.FindName(name);
            }
 
            return null;
        } 
 

        #endregion Public Methods 

        //------------------------------------------------------
        //
        //  Protected Methods 
        //
        //------------------------------------------------------ 
 
        #region Protected Methods
 
        /// 
        ///     Returns enumerator to logical children
        /// 
        protected internal virtual IEnumerator LogicalChildren 
        {
            get { return null; } 
        } 

        #endregion Protected Methods 

        //-----------------------------------------------------
        //
        //  Internal Methods 
        //
        //------------------------------------------------------ 
 
        #region Internal Methods
 
        /// 
        ///     Tries to find a Resource for the given resourceKey in the current
        ///     element's ResourceDictionary.
        ///  
        internal object FindResourceOnSelf(object resourceKey, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference)
        { 
            ResourceDictionary resources = ResourcesField.GetValue(this); 
            if ((resources != null) && resources.Contains(resourceKey))
            { 
                bool canCache;
                return resources.FetchResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache);
            }
 
            return DependencyProperty.UnsetValue;
        } 
 
        internal DependencyObject ContextVerifiedGetParent()
        { 
            return _parent;
        }

        // 

 
 

 
        protected internal void AddLogicalChild(object child)
        {
            if (child != null)
            { 
                // It is invalid to modify the children collection that we
                // might be iterating during a property invalidation tree walk. 
                if (IsLogicalChildrenIterationInProgress) 
                {
                    throw new InvalidOperationException(SR.Get(SRID.CannotModifyLogicalChildrenDuringTreeWalk)); 
                }

                // Now that the child is going to be added, the FE/FCE construction is considered finished,
                // so we do not expect a change of InheritanceBehavior property, 
                // so we can pick up properties from styles and resources.
                TryFireInitialized(); 
 
                bool exceptionThrown = true;
                try 
                {
                    HasLogicalChildren = true;

                    // Child is present; reparent him to this element 
                    FrameworkObject fo = new FrameworkObject(child as DependencyObject);
                    fo.ChangeLogicalParent(this); 
 
                    exceptionThrown = false;
                } 
                finally
                {
                    if (exceptionThrown)
                    { 
                        //
 
 
                        // Consider doing this...
                        //RemoveLogicalChild(child); 
                    }
                }
            }
        } 

 
        // 

 



        protected internal void RemoveLogicalChild(object child) 
        {
            if (child != null) 
            { 
                // It is invalid to modify the children collection that we
                // might be iterating during a property invalidation tree walk. 
                if (IsLogicalChildrenIterationInProgress)
                {
                    throw new InvalidOperationException(SR.Get(SRID.CannotModifyLogicalChildrenDuringTreeWalk));
                } 

                // Child is present 
                FrameworkObject fo = new FrameworkObject(child as DependencyObject); 
                if (fo.Parent == this)
                { 
                    fo.ChangeLogicalParent(null);
                }

                // This could have been the last child, so check if we have any more children 
                IEnumerator children = LogicalChildren;
 
                // if null, there are no children. 
                if (children == null)
                { 
                    HasLogicalChildren = false;
                }
                else
                { 
                    // If we can move next, there is at least one child
                    HasLogicalChildren = children.MoveNext(); 
                } 
            }
        } 

        /// 
        ///     Invoked when logical parent is changed.  This just
        ///     sets the parent pointer. 
        /// 
        ///  
        ///     A parent change is considered catastrohpic and results in a large 
        ///     amount of invalidations and tree traversals. 
        ///     is recommended to reduce the work necessary to build a tree 
        /// 
        /// 
        ///     New parent that was set
        ///  
        internal void ChangeLogicalParent(DependencyObject newParent)
        { 
            /////////////////// 
            // OnNewParent:
            /////////////////// 

            //
            // -- Approved By The Core Team --
            // 
            // Do not allow foreign threads to change the tree.
            // (This is a noop if this object is not assigned to a Dispatcher.) 
            // 
            // We also need to ensure that the tree is homogenous with respect
            // to the dispatchers that the elements belong to. 
            //
            this.VerifyAccess();
            if(newParent != null)
            { 
                newParent.VerifyAccess();
            } 
 
            // Logical Parent must first be dropped before you are attached to a newParent
            // This mitigates illegal tree state caused by logical child stealing as illustrated in bug 970706 
            if (_parent != null && newParent != null && _parent != newParent)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.HasLogicalParent));
            } 

            // Trivial check to avoid loops 
            if (newParent == this) 
            {
                throw new System.InvalidOperationException(SR.Get(SRID.CannotBeSelfParent)); 
            }

            // Logical Parent implies no InheritanceContext
            if (newParent != null) 
            {
                ClearInheritanceContext(); 
            } 

            IsParentAnFE = newParent is FrameworkElement; 

            DependencyObject oldParent = _parent;
            OnNewParent(newParent);
 
            // Update Has[Loaded/Unloaded]Handler Flags
            BroadcastEventHelper.AddOrRemoveHasLoadedChangeHandlerFlag(this, oldParent, newParent); 
 

            // Fire Loaded and Unloaded Events 
            BroadcastEventHelper.BroadcastLoadedOrUnloadedEvent(this, oldParent, newParent);


            /////////////////// 
            // OnParentChanged:
            /////////////////// 
 
            // Invalidate relevant properties for this subtree
            DependencyObject parent = (newParent != null) ? newParent : oldParent; 
            TreeWalkHelper.InvalidateOnTreeChange(/* fe = */ null, /* fce = */ this, parent, (newParent != null));

            // If no one has called BeginInit then mark the element initialized and fire Initialized event
            // (non-parser programmatic tree building scenario) 
            TryFireInitialized();
        } 
 
        /// 
        ///     Called before the parent is chanded to the new value. 
        /// 
        internal virtual void OnNewParent(DependencyObject newParent)
        {
            // 
            // This API is only here for compatability with the old
            // behavior.  Note that FrameworkElement does not have 
            // this virtual, so why do we need it here? 
            //
 
            DependencyObject oldParent = _parent;
            _parent = newParent;

 
            // Synchronize ForceInherit properties
            if(_parent != null) 
            { 
                UIElement.SynchronizeForceInheritProperties(null, this, null, _parent);
            } 
            else
            {
                UIElement.SynchronizeForceInheritProperties(null, this, null, oldParent);
            } 

 
 
            // Synchronize ReverseInheritProperty Flags
            // 
            // NOTE: do this AFTER synchronizing force-inherited flags, since
            // they often effect focusability and such.
            this.SynchronizeReverseInheritPropertyFlags(oldParent, false);
        } 

        // OnAncestorChangedInternal variant when we know what type (FE/FCE) the 
        //  tree node is. 
        /// 
        ///     Critical: This code calls into PresentationSource.OnAncestorChanged which is link demand protected 
        ///     it does so only for content elements and not for FEs. But if called externally and configured
        ///     inappropriately it can be used to change the tree
        ///     TreatAsSafe: This does not let you get at the presentationsource which is what we do not want to expose
        ///  
        [SecurityCritical,SecurityTreatAsSafe]
            internal void OnAncestorChangedInternal(TreeChangeInfo parentTreeState) 
        { 
            // Cache the IsSelfInheritanceParent flag
            bool isSelfInheritanceParent = IsSelfInheritanceParent; 

            if (parentTreeState.Root != this)
            {
                // Clear the HasStyleChanged flag 
                HasStyleChanged = false;
                HasStyleInvalidated = false; 
 
            }
 
            // If this is a tree add operation update the ShouldLookupImplicitStyles
            // flag with respect to your parent.
            if (parentTreeState.IsAddOperation)
            { 
                FrameworkObject fo =
 
                    new FrameworkObject(null, this); 
                fo.SetShouldLookupImplicitStyles();
            } 

            // Invalidate ResourceReference properties
            if (HasResourceReference)
            { 
                // This operation may cause a style change and hence should be done before the call to
                // InvalidateTreeDependents as it relies on the HasStyleChanged flag 
                TreeWalkHelper.OnResourcesChanged(this, ResourcesChangeInfo.TreeChangeInfo, false); 
            }
 
            // If parent is a FrameworkElement
            // This is also an operation that could change the style
            FrugalObjectList currentInheritableProperties =
            InvalidateTreeDependentProperties(parentTreeState, isSelfInheritanceParent); 

            // we have inherited properties that changes as a result of the above; 
            // invalidation; push that list of inherited properties on the stack 
            // for the children to use
            parentTreeState.InheritablePropertiesStack.Push(currentInheritableProperties); 


            // Notify the PresentationSource that this element's ancestry may have changed.
            // We only need the ContentElement's because UIElements are taken care of 
            // through the Visual class.
            PresentationSource.OnAncestorChanged(this); 
 

            // Call OnAncestorChanged 
            OnAncestorChanged();

            // Notify mentees if they exist
            if (PotentiallyHasMentees) 
            {
                // Raise the ResourcesChanged Event so that ResourceReferenceExpressions 
                // on non-[FE/FCE] listening for this can then update their values 
                RaiseClrEvent(FrameworkElement.ResourcesChangedKey, EventArgs.Empty);
            } 
        }

        // Invalidate all the properties that may have changed as a result of
        //  changing this element's parent in the logical (and sometimes visual tree.) 
        internal FrugalObjectList InvalidateTreeDependentProperties(TreeChangeInfo parentTreeState, bool isSelfInheritanceParent)
        { 
            AncestorChangeInProgress = true; 

 
            try
            {
                // Style property is a special case of a non-inherited property that needs
                // invalidation for parent changes. Invalidate StyleProperty if it hasn't been 
                // locally set because local value takes precedence over implicit references
                if (!HasLocalStyle && (this != parentTreeState.Root)) 
                { 
                    UpdateStyleProperty();
                } 

                Style selfStyle = null;
                Style selfThemeStyle = null;
                DependencyObject templatedParent = null; 

                int childIndex = -1; 
                ChildRecord childRecord = new ChildRecord(); 
                bool isChildRecordValid = false;
 
                selfStyle = Style;
                selfThemeStyle = ThemeStyle;
                templatedParent = TemplatedParent;
                childIndex = TemplateChildIndex; 

                // StyleProperty could have changed during invalidation of ResourceReferenceExpressions if it 
                // were locally set or during the invalidation of unresolved implicitly referenced style 
                bool hasStyleChanged = HasStyleChanged;
 
                // Fetch selfStyle, hasStyleChanged and childIndex for the current node
                FrameworkElement.GetTemplatedParentChildRecord(templatedParent, childIndex, out childRecord, out isChildRecordValid);

                FrameworkElement parentFE; 
                FrameworkContentElement parentFCE;
                bool hasParent = FrameworkElement.GetFrameworkParent(this, out parentFE, out parentFCE); 
 
                DependencyObject parent = null;
                InheritanceBehavior parentInheritanceBehavior = InheritanceBehavior.Default; 
                if (hasParent)
                {
                    if (parentFE != null)
                    { 
                        parent = parentFE;
                        parentInheritanceBehavior = parentFE.InheritanceBehavior; 
                    } 
                    else
                    { 
                        parent = parentFCE;
                        parentInheritanceBehavior = parentFCE.InheritanceBehavior;
                    }
                } 

                if (!TreeWalkHelper.SkipNext(InheritanceBehavior) && !TreeWalkHelper.SkipNow(parentInheritanceBehavior)) 
                { 
                    // Synchronize InheritanceParent
                    this.SynchronizeInheritanceParent(parent); 
                }
                else if (!IsSelfInheritanceParent)
                {
                    // Set IsSelfInheritanceParet on the root node at a tree boundary 
                    // so that all inheritable properties are cached on it.
                    SetIsSelfInheritanceParent(); 
                } 

                // Loop through all cached inheritable properties for the parent to see if they should be invalidated. 
                return TreeWalkHelper.InvalidateTreeDependentProperties(parentTreeState, /* fe = */ null, /* fce = */ this, selfStyle, selfThemeStyle,
                    ref childRecord, isChildRecordValid, hasStyleChanged, isSelfInheritanceParent);
            }
            finally 
            {
                AncestorChangeInProgress = false; 
 
            }
        } 

        /// 
        ///    Check if the current element has a Loaded/Unloaded Change Handler.
        ///  
        /// 
        ///    This is called this when a loaded handler element is removed. 
        ///  We need to check if the parent should clear or maintain the 
        ///  SubtreeHasLoadedChangeHandler bit.   For example the parent may also
        ///  have a handler. 
        ///    This could be more efficent if it were a bit on the element,
        ///  set and cleared when the handler or templates state changes.  I expect
        ///  Event Handler state changes less often than element parentage.
        ///  
        internal bool ThisHasLoadedChangeEventHandler
        { 
            get 
            {
                    if (null != EventHandlersStore) 
                    {
                        if (EventHandlersStore.Contains(LoadedEvent) || EventHandlersStore.Contains(UnloadedEvent))
                        {
                            return true; 
                        }
                    } 
                    if(null != Style && Style.HasLoadedChangeHandler) 
                    {
                        return true; 
                    }
                    if(null != ThemeStyle && ThemeStyle.HasLoadedChangeHandler)
                    {
                        return true; 
                    }
 
                    if(HasFefLoadedChangeHandler) 
                    {
                        return true; 
                    }
                    return false;
                }
        } 

        internal bool HasFefLoadedChangeHandler 
        { 
            get
            { 
                if(null == TemplatedParent)
                {
                    return false;
                } 
                FrameworkElementFactory fefRoot = BroadcastEventHelper.GetFEFTreeRoot(TemplatedParent);
                if(null == fefRoot) 
                { 
                    return false;
                } 
                FrameworkElementFactory fef = StyleHelper.FindFEF(fefRoot, TemplateChildIndex);
                if(null == fef)
                {
                    return false; 
                }
                return fef.HasLoadedChangeHandler; 
            } 
        }
 

        /// 
        ///     This method causes the StyleProperty to be re-evaluated
        ///  
        internal void UpdateStyleProperty()
        { 
            if (!HasStyleInvalidated) 
            {
                if (IsStyleUpdateInProgress == false) 
                {
                    IsStyleUpdateInProgress = true;
                    try
                    { 
                        InvalidateProperty(StyleProperty);
                        HasStyleInvalidated = true; 
                    } 
                    finally
                    { 
                        IsStyleUpdateInProgress = false;
                    }
                }
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.CyclicStyleReferenceDetected, this)); 
                } 
            }
        } 

        /// 
        ///     This method causes the ThemeStyleProperty to be re-evaluated
        ///  
        internal void UpdateThemeStyleProperty()
        { 
            if (IsThemeStyleUpdateInProgress == false) 
            {
                IsThemeStyleUpdateInProgress = true; 
                try
                {
                    StyleHelper.GetThemeStyle(/* fe = */ null, /* fce = */ this);
 
                    // Update the ContextMenu and ToolTips separately because they aren't in the tree
                    ContextMenu contextMenu = 
                            GetValueEntry( 
                                    LookupEntry(ContextMenuProperty.GlobalIndex),
                                    ContextMenuProperty, 
                                    null,
                                    RequestFlags.DeferredReferences).Value as ContextMenu;
                    if (contextMenu != null)
                    { 
                        TreeWalkHelper.InvalidateOnResourcesChange(contextMenu, null, ResourcesChangeInfo.ThemeChangeInfo);
                    } 
 
                    DependencyObject toolTip =
                            GetValueEntry( 
                                    LookupEntry(ToolTipProperty.GlobalIndex),
                                    ToolTipProperty,
                                    null,
                                    RequestFlags.DeferredReferences).Value as DependencyObject; 

                    if (toolTip != null) 
                    { 
                        FrameworkObject toolTipFO = new FrameworkObject(toolTip);
                        if (toolTipFO.IsValid) 
                        {
                            TreeWalkHelper.InvalidateOnResourcesChange(toolTipFO.FE, toolTipFO.FCE, ResourcesChangeInfo.ThemeChangeInfo);
                        }
                    } 

                    OnThemeChanged(); 
                } 
                finally
                { 
                    IsThemeStyleUpdateInProgress = false;
                }
            }
            else 
            {
                throw new InvalidOperationException(SR.Get(SRID.CyclicThemeStyleReferenceDetected, this)); 
            } 
        }
 
        // Called when the theme changes so resources not in the tree can be updated by subclasses
        internal virtual void OnThemeChanged()
        {
        } 

        /// 
        ///     Initiate the processing for Loaded event broadcast starting at this node 
        /// 
        ///  
        ///     This method is to allow firing Loaded event from a Helper class since the override is protected
        /// 
        internal void FireLoadedOnDescendentsInternal()
        { 
            // This is to prevent duplicate Broadcasts for the Loaded event
            if (LoadedPending == null) 
            { 
                DependencyObject parent = Parent;
 

                // Check if this Loaded cancels against a previously queued Unloaded event
                // Note that if the Loaded and the Unloaded do not change the position of
                // the node within the loagical tree they are considered to cancel each other out. 
                object[] unloadedPending = UnloadedPending;
                if (unloadedPending == null || unloadedPending[2] != parent) 
                { 
                    // Add a callback to the MediaContext which will be called
                    // before the first render after this point 
                    BroadcastEventHelper.AddLoadedCallback(this, parent);
                }
                else
                { 
                    // Dequeue Unloaded
                    BroadcastEventHelper.RemoveUnloadedCallback(this, unloadedPending); 
                } 
            }
        } 

        ///
        ///     Broadcast Unloaded event starting at this node
        ///  
        internal void FireUnloadedOnDescendentsInternal()
        { 
            // This is to prevent duplicate Broadcasts for the Unloaded event 
            if (UnloadedPending == null)
            { 
                DependencyObject parent = Parent;


                // Check if this Unloaded cancels against a previously queued Loaded event 
                // Note that if the Loaded and the Unloaded do not change the position of
                // the node within the loagical tree they are considered to cancel each other out. 
                object[] loadedPending = LoadedPending; 
                if (loadedPending == null)
                { 
                    // Add a callback to the MediaContext which will be called
                    // before the first render after this point
                    BroadcastEventHelper.AddUnloadedCallback(this, parent);
                } 
                else
                { 
                    // Dequeue Loaded 
                    BroadcastEventHelper.RemoveLoadedCallback(this, loadedPending);
                } 
            }
        }

        ///  
        ///     You are about to provided as the InheritanceContext for the target.
        ///     You can choose to allow this or not. 
        ///  
        internal override bool ShouldProvideInheritanceContext(DependencyObject target, DependencyProperty property)
        { 
            // return true if the target is neither a FE or FCE
            FrameworkObject fo = new FrameworkObject(target);
            return !fo.IsValid;
        } 

        // Define the DO's inheritance context 
        internal override DependencyObject InheritanceContext 
        {
            get { return InheritanceContextField.GetValue(this); } 
        }

        /// 
        ///     You have a new InheritanceContext 
        /// 
        ///  
        ///     This is to solve the case of programmatically creating a VisualBrush or BitmapCacheBrush 
        ///     with an element in it and the element not getting Initialized.
        ///  
        internal override void AddInheritanceContext(DependencyObject context, DependencyProperty property)
        {
            base.AddInheritanceContext(context, property);
 
            // Initialize, if not already done
            TryFireInitialized(); 
 
            // accept the new inheritance context provided that
            // a) the requested link uses VisualBrush.Visual or BitmapCacheBrush.TargetProperty 
            // b) this element has no visual or logical parent
            // c) the context does not introduce a cycle
            if ((property == VisualBrush.VisualProperty || property == BitmapCacheBrush.TargetProperty)
                && FrameworkElement.GetFrameworkParent(this) == null 
                 //!FrameworkObject.IsEffectiveAncestor(this, context, property))
                && !FrameworkObject.IsEffectiveAncestor(this, context)) 
            { 
                //FrameworkObject.Log("+ {0}", FrameworkObject.LogIC(context, property, this));
                if (!HasMultipleInheritanceContexts && InheritanceContext == null) 
                {
                    // first request - accept the new inheritance context
                    InheritanceContextField.SetValue(this, context);
                    OnInheritanceContextChanged(EventArgs.Empty); 
                }
                else if (InheritanceContext != null) 
                { 
                    // second request - remove all context and enter "shared" mode
                    InheritanceContextField.ClearValue(this); 
                    WriteInternalFlag2(InternalFlags2.HasMultipleInheritanceContexts, true);
                    OnInheritanceContextChanged(EventArgs.Empty);
                }
                // else already in shared mode - ignore the request 
            }
        } 
 
        // Remove an inheritance context
        internal override void RemoveInheritanceContext(DependencyObject context, DependencyProperty property) 
        {
            if (InheritanceContext == context)
            {
                //FrameworkObject.Log("- {0}", FrameworkObject.LogIC(context, property, this)); 
                InheritanceContextField.ClearValue(this);
                OnInheritanceContextChanged(EventArgs.Empty); 
            } 

            base.RemoveInheritanceContext(context, property); 
        }

        // Clear the inheritance context (called when the element
        // gets a real parent 
        private void ClearInheritanceContext()
        { 
            if (InheritanceContext != null) 
            {
                InheritanceContextField.ClearValue(this); 
                OnInheritanceContextChanged(EventArgs.Empty);
            }
        }
 
        /// 
        ///     This is a means for subclasses to get notification 
        ///     of InheritanceContext changes and then they can do 
        ///     their own thing.
        ///  
        internal override void OnInheritanceContextChangedCore(EventArgs args)
        {
            DependencyObject oldMentor = MentorField.GetValue(this);
            DependencyObject newMentor = Helper.FindMentor(InheritanceContext); 

            if (oldMentor != newMentor) 
            { 
                MentorField.SetValue(this, newMentor);
 
                if (oldMentor != null)
                {
                    DisconnectMentor(oldMentor);
                } 
                if (newMentor != null)
                { 
                    ConnectMentor(newMentor); 
                }
            } 
        }

        // connect to a new mentor
        void ConnectMentor(DependencyObject mentor) 
        {
            FrameworkObject foMentor = new FrameworkObject(mentor); 
 
            // register for InheritedPropertyChanged events
            foMentor.InheritedPropertyChanged += new InheritedPropertyChangedEventHandler(OnMentorInheritedPropertyChanged); 

            // register for ResourcesChanged events
            foMentor.ResourcesChanged += new EventHandler(OnMentorResourcesChanged);
 
            // invalidate the mentee's tree
            TreeWalkHelper.InvalidateOnTreeChange( 
 
                    null, this,
                    foMentor.DO, 
                    true /* isAddOperation */
                    );

            // register for Loaded/Unloaded events. 
            // Do this last so the tree is ready when Loaded is raised.
            if (this.SubtreeHasLoadedChangeHandler) 
            { 
                bool isLoaded = foMentor.IsLoaded;
 
                ConnectLoadedEvents(ref foMentor, isLoaded);

                if (isLoaded)
                { 
                    this.FireLoadedOnDescendentsInternal();
                } 
            } 
        }
 
        // disconnect from an old mentor
        void DisconnectMentor(DependencyObject mentor)
        {
            FrameworkObject foMentor = new FrameworkObject(mentor); 

            // unregister for InheritedPropertyChanged events 
            foMentor.InheritedPropertyChanged -= new InheritedPropertyChangedEventHandler(OnMentorInheritedPropertyChanged); 

            // unregister for ResourcesChanged events 
            foMentor.ResourcesChanged -= new EventHandler(OnMentorResourcesChanged);

            // invalidate the mentee's tree
            TreeWalkHelper.InvalidateOnTreeChange( 

                    null, this, 
                    foMentor.DO, 
                    false /* isAddOperation */
                    ); 

            // unregister for Loaded/Unloaded events
            if (this.SubtreeHasLoadedChangeHandler)
            { 
                bool isLoaded = foMentor.IsLoaded;
 
                DisconnectLoadedEvents(ref foMentor, isLoaded); 

                if (foMentor.IsLoaded) 
                {
                    this.FireUnloadedOnDescendentsInternal();
                }
            } 
        }
 
        // called by BroadcastEventHelper when the SubtreeHasLoadedChangedHandler 
        // flag changes on a mentored FE/FCE
        internal void ChangeSubtreeHasLoadedChangedHandler(DependencyObject mentor) 
        {
            FrameworkObject foMentor = new FrameworkObject(mentor);
            bool isLoaded = foMentor.IsLoaded;
 
            if (this.SubtreeHasLoadedChangeHandler)
            { 
                ConnectLoadedEvents(ref foMentor, isLoaded); 
            }
            else 
            {
                DisconnectLoadedEvents(ref foMentor, isLoaded);
            }
        } 

        // handle the Loaded event from the mentor 
        void OnMentorLoaded(object sender, RoutedEventArgs e) 
        {
            FrameworkObject foMentor = new FrameworkObject((DependencyObject)sender); 

            // stop listening for Loaded, start listening for Unloaded
            foMentor.Loaded -= new RoutedEventHandler(OnMentorLoaded);
            foMentor.Unloaded += new RoutedEventHandler(OnMentorUnloaded); 

            // broadcast the Loaded event to my framework subtree 
            //FireLoadedOnDescendentsInternal(); 
            BroadcastEventHelper.BroadcastLoadedSynchronously(this, IsLoaded);
        } 

        // handle the Unloaded event from the mentor
        void OnMentorUnloaded(object sender, RoutedEventArgs e)
        { 
            FrameworkObject foMentor = new FrameworkObject((DependencyObject)sender);
 
            // stop listening for Unloaded, start listening for Loaded 
            foMentor.Unloaded -= new RoutedEventHandler(OnMentorUnloaded);
            foMentor.Loaded += new RoutedEventHandler(OnMentorLoaded); 

            // broadcast the Unloaded event to my framework subtree
            //FireUnloadedOnDescendentsInternal();
            BroadcastEventHelper.BroadcastUnloadedSynchronously(this, IsLoaded); 
        }
 
        void ConnectLoadedEvents(ref FrameworkObject foMentor, bool isLoaded) 
        {
            if (foMentor.IsValid) 
            {
                if (isLoaded)
                {
                    foMentor.Unloaded += new RoutedEventHandler(OnMentorUnloaded); 
                }
                else 
                { 
                    foMentor.Loaded += new RoutedEventHandler(OnMentorLoaded);
                } 
            }
        }

        void DisconnectLoadedEvents(ref FrameworkObject foMentor, bool isLoaded) 
        {
            if (foMentor.IsValid) 
            { 
                if (isLoaded)
                { 
                    foMentor.Unloaded -= new RoutedEventHandler(OnMentorUnloaded);
                }
                else
                { 
                    foMentor.Loaded -= new RoutedEventHandler(OnMentorLoaded);
                } 
            } 
        }
 
        // handle the InheritedPropertyChanged event from the mentor
        void OnMentorInheritedPropertyChanged(object sender, InheritedPropertyChangedEventArgs e)
        {
            TreeWalkHelper.InvalidateOnInheritablePropertyChange( 

                    null, this, 
                    e.Info, false /*skipStartNode*/); 
        }
 
        // handle the ResourcesChanged event from the mentor
        void OnMentorResourcesChanged(object sender, EventArgs e)
        {
            TreeWalkHelper.InvalidateOnResourcesChange( 

                    null, this, 
                    ResourcesChangeInfo.CatastrophicDictionaryChangeInfo); 
        }
 
        // 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);
                }
            } 
        }
 
        #endregion Internal Methods 

        //----------------------------------------------------- 
        //
        //  Internal Properties
        //
        //----------------------------------------------------- 

        #region Internal Properties 
 
        // Indicates if the Style is being re-evaluated
        internal bool IsStyleUpdateInProgress 
        {
            get { return ReadInternalFlag(InternalFlags.IsStyleUpdateInProgress); }
            set { WriteInternalFlag(InternalFlags.IsStyleUpdateInProgress, value); }
        } 

        // Indicates if the ThemeStyle is being re-evaluated 
        internal bool IsThemeStyleUpdateInProgress 
        {
            get { return ReadInternalFlag(InternalFlags.IsThemeStyleUpdateInProgress); } 
            set { WriteInternalFlag(InternalFlags.IsThemeStyleUpdateInProgress, value); }
        }

        // Indicates that we are storing "container template" provided values 
        // on this element -- see StyleHelper.ParentTemplateValuesField
        internal bool StoresParentTemplateValues 
        { 
            get { return ReadInternalFlag(InternalFlags.StoresParentTemplateValues); }
            set { WriteInternalFlag(InternalFlags.StoresParentTemplateValues, value); } 
        }

        // Indicates if this instance has had NumberSubstitutionChanged on it
        internal bool HasNumberSubstitutionChanged 
        {
            get { return ReadInternalFlag(InternalFlags.HasNumberSubstitutionChanged); } 
            set { WriteInternalFlag(InternalFlags.HasNumberSubstitutionChanged, value); } 
        }
 
        // Indicates if this instance has a tree that
        // was generated via a Template
        internal bool HasTemplateGeneratedSubTree
        { 
            get { return ReadInternalFlag(InternalFlags.HasTemplateGeneratedSubTree); }
            set { WriteInternalFlag(InternalFlags.HasTemplateGeneratedSubTree, value); } 
        } 

        // Indicates if this instance has an implicit style 
        internal bool HasImplicitStyleFromResources
        {
            get { return ReadInternalFlag(InternalFlags.HasImplicitStyleFromResources); }
            set { WriteInternalFlag(InternalFlags.HasImplicitStyleFromResources, value); } 
        }
 
        // Indicates if there are any implicit styles in the ancestry 
        internal bool ShouldLookupImplicitStyles
        { 
            get { return ReadInternalFlag(InternalFlags.ShouldLookupImplicitStyles); }
            set { WriteInternalFlag(InternalFlags.ShouldLookupImplicitStyles, value); }
        }
 
        // Indicates if this instance has a style set by a generator
        internal bool IsStyleSetFromGenerator 
        { 
            get { return ReadInternalFlag2(InternalFlags2.IsStyleSetFromGenerator); }
            set { WriteInternalFlag2(InternalFlags2.IsStyleSetFromGenerator, value); } 
        }

        // Indicates if the StyleProperty has changed following a UpdateStyleProperty
        // call in OnAncestorChangedInternal 
        internal bool HasStyleChanged
        { 
            get { return ReadInternalFlag2(InternalFlags2.HasStyleChanged); } 
            set { WriteInternalFlag2(InternalFlags2.HasStyleChanged, value); }
        } 



        // Indicates if the StyleProperty has been invalidated during a tree walk 
        internal bool HasStyleInvalidated
        { 
            get { return ReadInternalFlag2(InternalFlags2.HasStyleInvalidated); } 
            set { WriteInternalFlag2(InternalFlags2.HasStyleInvalidated, value); }
        } 

        // Indicates that the StyleProperty full fetch has been
        // performed atleast once on this node
        internal bool HasStyleEverBeenFetched 
        {
            get { return ReadInternalFlag(InternalFlags.HasStyleEverBeenFetched); } 
            set { WriteInternalFlag(InternalFlags.HasStyleEverBeenFetched, value); } 
        }
 
        // Indicates that the StyleProperty has been set locally on this element
        internal bool HasLocalStyle
        {
            get { return ReadInternalFlag(InternalFlags.HasLocalStyle); } 
            set { WriteInternalFlag(InternalFlags.HasLocalStyle, value); }
        } 
 
        // Indicates that the ThemeStyleProperty full fetch has been
        // performed atleast once on this node 
        internal bool HasThemeStyleEverBeenFetched
        {
            get { return ReadInternalFlag(InternalFlags.HasThemeStyleEverBeenFetched); }
            set { WriteInternalFlag(InternalFlags.HasThemeStyleEverBeenFetched, value); } 
        }
 
        // Indicates that an ancestor change tree walk is progressing 
        // through the given node
        internal bool AncestorChangeInProgress 
        {
            get { return ReadInternalFlag(InternalFlags.AncestorChangeInProgress); }
            set { WriteInternalFlag(InternalFlags.AncestorChangeInProgress, value); }
        } 

        // Stores the inheritable properties that will need to invalidated on the children of this 
        // node.This is a transient cache that is active only during an AncestorChange operation. 
        internal FrugalObjectList InheritableProperties
        { 
            get { return _inheritableProperties; }
            set { _inheritableProperties = value; }
        }
 
        // Says if there is a loaded event pending
        internal object[] LoadedPending 
        { 
            get { return (object[]) GetValue(LoadedPendingProperty); }
        } 

        // Says if there is an unloaded event pending
        internal object[] UnloadedPending
        { 
            get { return (object[]) GetValue(UnloadedPendingProperty); }
        } 
 
        // Indicates if this instance has multiple inheritance contexts
        internal override bool HasMultipleInheritanceContexts 
        {
            get { return ReadInternalFlag2(InternalFlags2.HasMultipleInheritanceContexts); }
        }
 
        // Indicates if the current element has or had mentees at some point.
        internal bool PotentiallyHasMentees 
        { 
            get { return ReadInternalFlag(InternalFlags.PotentiallyHasMentees); }
            set 
            {
                Debug.Assert(value == true,
                    "This flag is set to true when a mentee attaches a listeners to either the " +
                    "InheritedPropertyChanged event or the ResourcesChanged event. It never goes " + 
                    "back to being false because this would involve counting the remaining listeners " +
                    "for either of the aforementioned events. This seems like an overkill for the perf " + 
                    "optimization we are trying to achieve here."); 

                WriteInternalFlag(InternalFlags.PotentiallyHasMentees, value); 
            }
        }

 

        ///  
        ///     ResourceReferenceExpressions on non-[FE/FCE] add listeners to this 
        ///     event so they can get notified when there is a ResourcesChange
        ///  
        /// 
        ///     make this pay-for-play by storing handlers
        ///     in EventHandlersStore
        ///  
        internal event EventHandler ResourcesChanged
        { 
            add 
            {
                PotentiallyHasMentees = true; 
                EventHandlersStoreAdd(FrameworkElement.ResourcesChangedKey, value);
            }
            remove { EventHandlersStoreRemove(FrameworkElement.ResourcesChangedKey, value); }
        } 

 
 
        /// 
        ///     Mentees add listeners to this 
        ///     event so they can get notified when there is a InheritedPropertyChange
        /// 
        /// 
        ///     make this pay-for-play by storing handlers 
        ///     in EventHandlersStore
        ///  
        internal event InheritedPropertyChangedEventHandler InheritedPropertyChanged 
        {
            add 
            {
                PotentiallyHasMentees = true;
                EventHandlersStoreAdd(FrameworkElement.InheritedPropertyChangedKey, value);
            } 
            remove { EventHandlersStoreRemove(FrameworkElement.InheritedPropertyChangedKey, value); }
        } 
 

        #endregion Internal Properties 

        //-----------------------------------------------------
        //
        //  Internal Fields 
        //
        //------------------------------------------------------ 
 
        #region Internal Fields
 
        // Optimization, to avoid calling FromSystemType too often
        internal new static DependencyObjectType DType = DependencyObjectType.FromSystemTypeInternal(typeof(FrameworkContentElement));

        #endregion Internal Fields 

        //----------------------------------------------------- 
        // 
        //  Private Fields
        // 
        //------------------------------------------------------

        #region Private Fields
 
        // The parent element in logical tree.
        private new DependencyObject _parent; 
        private FrugalObjectList _inheritableProperties; 

        private static readonly UncommonField InheritanceContextField = new UncommonField(); 
        private static readonly UncommonField MentorField = new UncommonField();

        #endregion Private Fields
    } 
}

// 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