// Token: 0x060064AD RID: 25773 RVA: 0x001C3DF0 File Offset: 0x001C1FF0
 internal void SetShouldLookupImplicitStyles()
 {
     if (!this.ShouldLookupImplicitStyles)
     {
         FrameworkObject frameworkParent = this.FrameworkParent;
         if (frameworkParent.IsValid && frameworkParent.ShouldLookupImplicitStyles)
         {
             this.ShouldLookupImplicitStyles = true;
         }
     }
 }
Example #2
0
 // Set the ShouldLookupImplicitStyles flag on the current
 // node if the parent has it set to true.
 internal void SetShouldLookupImplicitStyles()
 {
     if (!ShouldLookupImplicitStyles)
     {
         FrameworkObject parent = FrameworkParent;
         if (parent.IsValid && parent.ShouldLookupImplicitStyles)
         {
             ShouldLookupImplicitStyles = true;
         }
     }
 }
 // Token: 0x0600647E RID: 25726 RVA: 0x001C3364 File Offset: 0x001C1564
 internal FrameworkObject(DependencyObject d, bool throwIfNeither)
 {
     this = new FrameworkObject(d);
     if (throwIfNeither && this._fe == null && this._fce == null)
     {
         object obj = (d != null) ? d.GetType() : "NULL";
         throw new InvalidOperationException(SR.Get("MustBeFrameworkDerived", new object[]
         {
             obj
         }));
     }
 }
        // Token: 0x060064A1 RID: 25761 RVA: 0x001C3AA4 File Offset: 0x001C1CA4
        internal static bool IsEffectiveAncestor(DependencyObject d1, DependencyObject d2)
        {
            FrameworkObject frameworkObject = new FrameworkObject(d2);

            while (frameworkObject.DO != null)
            {
                if (frameworkObject.DO == d1)
                {
                    return(true);
                }
                frameworkObject.Reset(frameworkObject.EffectiveParent);
            }
            return(false);
        }
        // Token: 0x060064A6 RID: 25766 RVA: 0x001C3B9C File Offset: 0x001C1D9C
        internal FrameworkObject GetPreferVisualParent(bool force)
        {
            InheritanceBehavior inheritanceBehavior = force ? InheritanceBehavior.Default : this.InheritanceBehavior;

            if (inheritanceBehavior != InheritanceBehavior.Default)
            {
                return(new FrameworkObject(null));
            }
            FrameworkObject rawPreferVisualParent = this.GetRawPreferVisualParent();

            switch (rawPreferVisualParent.InheritanceBehavior)
            {
            case InheritanceBehavior.SkipToAppNow:
            case InheritanceBehavior.SkipToThemeNow:
            case InheritanceBehavior.SkipAllNow:
                rawPreferVisualParent.Reset(null);
                break;
            }
            return(rawPreferVisualParent);
        }
        /// <summary>
        ///     Notification that the ResourceReferenceExpression has been set as a property's value
        /// </summary>
        /// <param name="d">DependencyObject being set</param>
        /// <param name="dp">Property being set</param>
        internal override void OnAttach(DependencyObject d, DependencyProperty dp)
        {
            _targetObject = d;
            _targetProperty = dp;

            FrameworkObject fo = new FrameworkObject(_targetObject);

            fo.HasResourceReference = true;

            if (!fo.IsValid)
            {
                // Listen for the InheritanceContextChanged event on the target node,
                // so that if this context hierarchy changes we can re-evaluate this expression.
                _targetObject.InheritanceContextChanged += new EventHandler(InvalidateExpressionValue);
            }
        }
Example #7
0
        // FindResourceInTree(fe/fce)  Defaults: none
        internal static object FindResourceInTree( 
            FrameworkElement        feStart,
            FrameworkContentElement fceStart,
            DependencyProperty      dp,
            object                  resourceKey, 
            object                  unlinkedParent,
            bool                    allowDeferredResourceReference, 
            bool                    mustReturnDeferredResourceReference, 
            DependencyObject        boundaryElement,
            out InheritanceBehavior inheritanceBehavior, 
            out object              source)
        {
            FrameworkObject startNode = new FrameworkObject(feStart, fceStart);
            FrameworkObject fo = startNode; 
            object value;
            Style style; 
            FrameworkTemplate frameworkTemplate; 
            Style themeStyle;
            int loopCount = 0; 
            bool hasParent = true;
            inheritanceBehavior = InheritanceBehavior.Default;

            while (hasParent) 
            {
                Debug.Assert(startNode.IsValid || unlinkedParent != null, 
                              "Don't call FindResource with a null fe/fce and unlinkedParent"); 

                if (loopCount > ContextLayoutManager.s_LayoutRecursionLimit) 
                {
                    // We suspect a loop here because the loop count
                    // has exceeded the MAX_TREE_DEPTH expected
                    throw new InvalidOperationException(SR.Get(SRID.LogicalTreeLoop)); 
                }
                else 
                { 
                    loopCount++;
                } 

                // -------------------------------------------
                //  Lookup ResourceDictionary on the current instance
                // ------------------------------------------- 

                style = null; 
                frameworkTemplate = null; 
                themeStyle = null;
 
                if (fo.IsFE)
                {
                    FrameworkElement fe = fo.FE;
 
                    value = fe.FindResourceOnSelf(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference);
                    if (value != DependencyProperty.UnsetValue) 
                    { 
                        source = fe;
 
                        if( TraceResourceDictionary.IsEnabled )
                        {
                            TraceResourceDictionary.TraceActivityItem(
                                TraceResourceDictionary.FoundResourceOnElement, 
                                source,
                                resourceKey, 
                                value ); 
                        }
 
                        return value;
                    }

                    if ((fe != startNode.FE) || StyleHelper.ShouldGetValueFromStyle(dp)) 
                    {
                        style = fe.Style; 
                    } 
                    // Fetch the Template
                    if ((fe != startNode.FE) || StyleHelper.ShouldGetValueFromTemplate(dp)) 
                    {
                        frameworkTemplate = fe.TemplateInternal;
                    }
                    // Fetch the ThemeStyle 
                    if ((fe != startNode.FE) || StyleHelper.ShouldGetValueFromThemeStyle(dp))
                    { 
                        themeStyle = fe.ThemeStyle; 
                    }
                } 
                else if (fo.IsFCE)
                {
                    FrameworkContentElement fce = fo.FCE;
 
                    value = fce.FindResourceOnSelf(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference);
                    if (value != DependencyProperty.UnsetValue) 
                    { 
                        source = fce;
 
                        if( TraceResourceDictionary.IsEnabled )
                        {
                            TraceResourceDictionary.TraceActivityItem(
                                TraceResourceDictionary.FoundResourceOnElement, 
                                source,
                                resourceKey, 
                                value ); 
                        }
 
                        return value;
                    }

                    if ((fce != startNode.FCE) || StyleHelper.ShouldGetValueFromStyle(dp)) 
                    {
                        style = fce.Style; 
                    } 
                    // Fetch the ThemeStyle
                    if ((fce != startNode.FCE) || StyleHelper.ShouldGetValueFromThemeStyle(dp)) 
                    {
                        themeStyle = fce.ThemeStyle;
                    }
                } 

                if (style != null) 
                { 
                    value = style.FindResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference);
                    if (value != DependencyProperty.UnsetValue) 
                    {
                        source = style;

                        if( TraceResourceDictionary.IsEnabled ) 
                        {
                            TraceResourceDictionary.TraceActivityItem( 
                                TraceResourceDictionary.FoundResourceInStyle, 
                                style.Resources,
                                resourceKey, 
                                style,
                                fo.DO,
                                value );
                        } 

                        return value; 
                    } 
                }
                if (frameworkTemplate != null) 
                {
                    value = frameworkTemplate.FindResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference);
                    if (value != DependencyProperty.UnsetValue)
                    { 
                        source = frameworkTemplate;
 
                        if( TraceResourceDictionary.IsEnabled ) 
                        {
                            TraceResourceDictionary.TraceActivityItem( 
                                TraceResourceDictionary.FoundResourceInTemplate,
                                frameworkTemplate.Resources,
                                resourceKey,
                                frameworkTemplate, 
                                fo.DO,
                                value ); 
                        } 

                        return value; 
                    }
                }

                if (themeStyle != null) 
                {
                    value = themeStyle.FindResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference); 
                    if (value != DependencyProperty.UnsetValue) 
                    {
                        source = themeStyle; 

                        if( TraceResourceDictionary.IsEnabled )
                        {
                            TraceResourceDictionary.TraceActivityItem( 
                                TraceResourceDictionary.FoundResourceInThemeStyle,
                                themeStyle.Resources, 
                                resourceKey, 
                                themeStyle,
                                fo.DO, 
                                value );
                        }

                        return value; 
                    }
                } 
 

                // If the current element that has been searched is the boundary element 
                // then we need to progress no further
                if (boundaryElement != null && (fo.DO == boundaryElement))
                {
                    break; 
                }
 
                // If the current element for resource lookup is marked such 
                // then skip to the Application and/or System resources
                if (fo.IsValid && TreeWalkHelper.SkipNext(fo.InheritanceBehavior)) 
                {
                    inheritanceBehavior = fo.InheritanceBehavior;
                    break;
                } 

                // ------------------------------------------- 
                //  Find the next parent instance to lookup 
                // -------------------------------------------
 
                if (unlinkedParent != null)
                {
                    // This is for the special case when the parser tries to fetch
                    // a resource on an element even before it is hooked to the 
                    // tree. In this case the parser passes us the unlinkedParent
                    // to use it for resource lookup. 
                    DependencyObject unlinkedParentAsDO = unlinkedParent as DependencyObject; 
                    if (unlinkedParentAsDO != null)
                    { 
                        fo.Reset(unlinkedParentAsDO);
                        if (fo.IsValid)
                        {
                            hasParent = true; 
                        }
                        else 
                        { 
                            DependencyObject doParent = GetFrameworkParent(unlinkedParent);
                            if (doParent != null) 
                            {
                                fo.Reset(doParent);
                                hasParent = true;
                            } 
                            else
                            { 
                                hasParent = false; 
                            }
                        } 
                    }
                    else
                    {
                        hasParent = false; 
                    }
                    unlinkedParent = null; 
                } 
                else
                { 
                    Debug.Assert(fo.IsValid,
                                  "The current node being processed should be an FE/FCE");

                    fo = fo.FrameworkParent; 

                    hasParent = fo.IsValid; 
                } 

                // If the current element for resource lookup is marked such 
                // then skip to the Application and/or System resources
                if (fo.IsValid && TreeWalkHelper.SkipNow(fo.InheritanceBehavior))
                {
                    inheritanceBehavior = fo.InheritanceBehavior; 
                    break;
                } 
            } 

            // No matching resource was found in the tree 
            source = null;
            return DependencyProperty.UnsetValue;
        }
Example #8
0
        private bool ReceivePropertySet(object targetObject, XamlMember member,
            object value, DependencyObject templatedParent)
        {
            DependencyObject dependencyObject = targetObject as DependencyObject;
            DependencyProperty dependencyProperty;
            System.Windows.Baml2006.WpfXamlMember wpfMember = member as System.Windows.Baml2006.WpfXamlMember;
            if (wpfMember != null)
            {
                dependencyProperty = wpfMember.DependencyProperty;
            }
            else
            {
                // All DP backed XamlMembers must be wrapped by the WpfXamlMember.  If it isn't wrapped, then it's not a DP
                return false;
            }

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

            FrameworkObject fo = new FrameworkObject(dependencyObject);

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

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

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

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

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

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

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

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

            // Check if it is an expression

            Expression expr;
            int childIndex = fo.TemplateChildIndex;


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

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

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

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

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

                    TemplateBindingExtension templateBindingExtension = templateBindingExpr.TemplateBindingExtension;

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

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

                    // Create a Binding equivalent to the TemplateBindingExtension

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

                    value = binding;

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

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

            parentTemplateValues[dependencyProperty] = value;

            dependencyObject.ProvideSelfAsInheritanceContext(value, dependencyProperty);

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

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

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

            return true;
        }
Example #9
0
        /// <summary>
        ///     Invalidate inheritable properties and resource 
        ///     references during a tree change operation. 
        /// </summary>
        internal static void InvalidateOnTreeChange( 
            FrameworkElement        fe,
            FrameworkContentElement fce,
            DependencyObject        parent,
            bool                    isAddOperation) 
        {
            Debug.Assert(fe != null || fce != null, "Node with the tree change notification must be an FE or an FCE."); 
            Debug.Assert(parent != null, "Must have a parent that the current node is connected to or disconnected from."); 

            // If the tree change is for a non-FE/FCE parent then we need to find 
            // the nearest FE/FCE parent inorder to propagate inheritance correctly.
            FrameworkObject parentFO = new FrameworkObject(parent);
            if (!parentFO.IsValid)
            { 
                parent = parentFO.FrameworkParent.DO;
            } 
 
            // We're interested in changes to the Template property that occur during
            // the walk - if the template has changed we don't need to invalidate 
            // template-driven properties a second time.  The HasTemplateChanged property
            // is cleared on the first visit to each node, so that it means "template
            // changed during the walk".  But one relevant node isn't visited during
            // the walk - the templated parent of the initial node.  So we handle that now. 
            FrameworkObject fo = new FrameworkObject(fe, fce);
 
            // Synchronize the ShouldLookupImplicitStyles flag with respect to the parent here 
            // because for the root node of a tree change UpdateStyleProperty happens right here
            // in this method. And we need to have synchrnozed the ShouldLookupImplicitStyles 
            // before we re-query the Style property.

            if (isAddOperation)
            { 
                fo.SetShouldLookupImplicitStyles();
            } 
 
            fo.Reset(fo.TemplatedParent);
            fo.HasTemplateChanged = false; 

            DependencyObject d = (fe != null) ? (DependencyObject)fe : (DependencyObject)fce;

            // during a tree walk to invalidate inherited properties, we typically 
            // call UpdateStyle from FE/FCE.InvalidateTreeDependentProperties.  But
            // for the root element of the tree change, we need to record old values 
            // for inherited properties before we've updated the inheritance parent; 
            // so do the updatestyle here before we record old values so that we
            // capture any updates provided by styles. 
            if (fe != null)
            {
                if (fe.IsInitialized && !fe.HasLocalStyle)
                { 
                    // Clear the HasStyleChanged flag
                    fe.HasStyleChanged = false; 
                    fe.HasStyleInvalidated = false; 
                    fe.HasTemplateChanged = false;
 
                    fe.AncestorChangeInProgress = true;
                    fe.UpdateStyleProperty();
                    fe.AncestorChangeInProgress = false;
                } 
            }
            else 
            { 
                if (!fce.HasLocalStyle)
                { 
                    // Clear the HasStyleChanged flag
                    fce.HasStyleChanged = false;
                    fce.HasStyleInvalidated = false;
 
                    fce.AncestorChangeInProgress = true;
                    fce.UpdateStyleProperty(); 
                    fce.AncestorChangeInProgress = false; 
                }
            } 

            if (HasChildren(fe, fce))
            {
                // Spin up a DescendentsWalker only when 
                // the current node has children to walk
 
                // If there is another tree walk that has already visited the 
                // current node then we do not need to re-walk its sub-tree.
                FrameworkContextData fcdata = FrameworkContextData.From(d.Dispatcher); 
                if (!fcdata.WasNodeVisited(d, TreeChangeDelegate))
                {
                    // The TreeChangeInfo object is used here to track
                    // information that we have because we're doing a tree walk. 
                    TreeChangeInfo parentInfo = new TreeChangeInfo(d, parent, isAddOperation);
 
                    // PrePostDescendentsWalker is used instead of the standard 
                    // DescendentsWalker because we need a "post" callback to know when
                    // to pop the parent's InheritableProperties cache from the stack. 
                    PrePostDescendentsWalker<TreeChangeInfo> walker = new PrePostDescendentsWalker<TreeChangeInfo>(
                        TreeWalkPriority.LogicalTree, TreeChangeDelegate, TreeChangePostDelegate, parentInfo);

                    fcdata.AddWalker(TreeChangeDelegate, walker); 

                    try 
                    { 
                        walker.StartWalk(d);
                    } 
                    finally
                    {
                        fcdata.RemoveWalker(TreeChangeDelegate, walker);
                    } 
                }
            } 
            else 
            {
                // Degenerate case when the current node is a leaf node and has no children. 

                TreeChangeInfo parentInfo = new TreeChangeInfo(d, parent, isAddOperation);

                // Degenerate case of OnAncestorChanged for a single node 
                OnAncestorChanged(fe, fce, parentInfo);
 
                // Degenerate case of OnPostAncestorChanged for a single node 
                OnPostAncestorChanged(d, parentInfo);
            } 
        }
Example #10
0
        internal static bool GetFrameworkParent(FrameworkContentElement current, out FrameworkElement feParent, out FrameworkContentElement fceParent)
        { 
            FrameworkObject fo = new FrameworkObject(null, current);

            fo = fo.FrameworkParent;
 
            feParent = fo.FE;
            fceParent = fo.FCE; 
 
            return fo.IsValid;
        } 
Example #11
0
        /// <summary> 
        ///     Determine if the current DependencyObject is a candidate for 
        ///     producing inheritable values
        /// </summary> 
        /// <remarks>
        ///     This is called by both InvalidateTree and GetValueCore
        /// </remarks>
        internal static bool IsInheritanceNode( 
            DependencyObject    d,
            DependencyProperty  dp, 
        out InheritanceBehavior inheritanceBehavior) 
        {
            // Assume can continue search 
            inheritanceBehavior = InheritanceBehavior.Default;

            // Get Framework metadata (if exists)
            FrameworkPropertyMetadata metadata = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata; 

            // Check for correct type of metadata 
            if (metadata != null) 
            {
                FrameworkObject fo = new FrameworkObject(d); 

                if (fo.IsValid)
                {
                    // If parent is a Framework type, then check if it is at a 
                    // tree separation boundary. Stop inheritance at the boundary unless
                    // overridden by the medata.OverridesInheritanceBehavior flag. 
 
                    // GetValue from Parent only if instance is not a TreeSeparator
                    // or fmetadata.OverridesInheritanceBehavior is set to override separated tree behavior 
                    if (fo.InheritanceBehavior != InheritanceBehavior.Default && !metadata.OverridesInheritanceBehavior)
                    {
                        // Hit a tree boundary
                        inheritanceBehavior = fo.InheritanceBehavior; 
                    }
                } 
                else 
                {
                    // If not a Framework type, then, this isn't an inheritance node. 
                    // Only Framework types know how to inherit

                    return false;
                } 

                // Check if metadata is marked as inheritable 
                if (metadata.Inherits) 
                {
                    return true; 
                }
            }

            // Not a framework type with inheritable metadata 
            return false;
        } 
Example #12
0
        /// <summary> 
        ///     Invalidate all the properties in the given
        ///     collection of inheritable properties 
        /// </summary> 
        /// <remarks>
        ///     This method is called during an [FE/FCE].OnAncestorChange 
        /// </remarks>
        internal static FrugalObjectList<DependencyProperty> InvalidateTreeDependentProperties(
            TreeChangeInfo                       info,
            FrameworkElement                     fe, 
            FrameworkContentElement              fce,
            Style                                selfStyle, 
            Style                                selfThemeStyle, 
            ref ChildRecord                      childRecord,
            bool                                 isChildRecordValid, 
            bool                                 hasStyleChanged,
            bool                                 isSelfInheritanceParent)
        {
            Debug.Assert(fe != null || fce != null, "Must have non-null current node"); 
            DependencyObject d = fe != null ? (DependencyObject)fe : (DependencyObject)fce;
            FrameworkObject fo = new FrameworkObject(fe, fce); 
 
            // Pull up the parent's InheritableProperties cache
            FrugalObjectList<DependencyProperty> parentInheritableProperties = info.InheritablePropertiesStack.Peek(); 

            // Loop through all cached inheritable
            // to see if they should be invalidated.
            int inheritablePropertiesCount = parentInheritableProperties  != null ? parentInheritableProperties.Count : 0; 

            FrugalObjectList<DependencyProperty> currentInheritableProperties = null; 
            if (HasChildren(fe, fce)) 
            {
                currentInheritableProperties = new FrugalObjectList<DependencyProperty>(inheritablePropertiesCount); 
            }

            info.ResetInheritableValueIndexer();
 
            for (int i = 0; i < inheritablePropertiesCount; i++)
            { 
                DependencyProperty inheritableProperty = parentInheritableProperties[i]; 

                Debug.Assert(inheritableProperty.IsPotentiallyInherited, "if we got here, it means that this property is inheritable by someone"); 

                PropertyMetadata metadata = inheritableProperty.GetMetadata(d);

                // Invalidate only properties that are marked as inheritable. 
                // These are the ones that will be affected by an ancestor changes.
                if (metadata.IsInherited) 
                { 
                    FrameworkPropertyMetadata fMetadata = (FrameworkPropertyMetadata)metadata;
 
                    bool changed = InvalidateTreeDependentProperty(info, d, ref fo, inheritableProperty, fMetadata,
                        selfStyle, selfThemeStyle, ref childRecord, isChildRecordValid, hasStyleChanged, isSelfInheritanceParent);

                    // If a change is detected then add the inheritable property to 
                    // the current list so that it can be used to invalidate further children
                    if (changed && currentInheritableProperties != null) 
                    { 
                        Debug.Assert(!currentInheritableProperties.Contains(inheritableProperty), "InheritableProperties list should not have duplicates");
 
                        // Children do not need to inherit properties across a tree boundary
                        // unless the property is set to override this behavior.

                        if (!SkipNow(fo.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior) 
                        {
                            currentInheritableProperties.Add(inheritableProperty); 
                        } 
                    }
                } 
            }

            return currentInheritableProperties;
        } 
        //
        //  Add a child to a parent, using IAddChild.  This has special support for Grid,
        //  to allow backward compatibility with FEF-based templates that have Column/RowDefinition
        //  children directly  under the Grid.
        //

        private void AddNodeToParent( DependencyObject parent, FrameworkObject childFrameworkObject )
        {
            Grid parentGrid;
            ColumnDefinition childNodeColumnDefinition;
            RowDefinition childNodeRowDefinition = null;

            if (    childFrameworkObject.IsFCE
                &&  (parentGrid = parent as Grid) != null
                &&  (   (childNodeColumnDefinition = childFrameworkObject.FCE as ColumnDefinition) != null
                    ||  (childNodeRowDefinition = childFrameworkObject.FCE as RowDefinition) != null  )
                )
            {
                if (childNodeColumnDefinition != null)
                {
                    parentGrid.ColumnDefinitions.Add(childNodeColumnDefinition);
                }
                else if (childNodeRowDefinition != null)
                {
                    parentGrid.RowDefinitions.Add(childNodeRowDefinition);
                }
            }
            else
            {
                // CALLBACK
                // Inheritable property invalidations will occur due to
                //   OnParentChanged resulting from AddChild

                if (!(parent is IAddChild))
                {
                    throw new InvalidOperationException(SR.Get(SRID.TypeMustImplementIAddChild,
                                                         parent.GetType().Name));
                }

                ((IAddChild)parent).AddChild(childFrameworkObject.DO);
            }
        }
        // This tree is used to instantiate a tree, represented by this factory.
        // It is instantiated as a normal tree without any template optimizations.
        // This is used by designers to inspect a template.

        internal FrameworkObject InstantiateUnoptimizedTree()
        {

            if (!_sealed)
            {
                throw new InvalidOperationException(SR.Get(SRID.FrameworkElementFactoryMustBeSealed));
            }

            // Create the object.

            FrameworkObject frameworkObject = new FrameworkObject(CreateDependencyObject());

            // Mark the beginning of initialization

            frameworkObject.BeginInit();

            // Set values for this object, taking them from the shared values table.

            ProvideValueServiceProvider provideValueServiceProvider = null;
            FrameworkTemplate.SetTemplateParentValues( Name, frameworkObject.DO, _frameworkTemplate, ref provideValueServiceProvider );

            // Get the first child

            FrameworkElementFactory childFactory = _firstChild;

            // If we have children, get this object's IAddChild, because it's going to be a parent.

            IAddChild iAddChild = null;
            if( childFactory != null )
            {
                iAddChild = frameworkObject.DO as IAddChild;
                if (iAddChild == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.TypeMustImplementIAddChild,
                                                         frameworkObject.DO.GetType().Name));
                }
            }

            // Build the children.

            while (childFactory != null)
            {

                if (childFactory._text != null)
                {
                    iAddChild.AddText(childFactory._text);

                }
                else
                {
                    // Use frameworkObject's IAddChild to add this node.
                    FrameworkObject childFrameworkObject = childFactory.InstantiateUnoptimizedTree();
                    AddNodeToParent(frameworkObject.DO, childFrameworkObject );
                }

                childFactory = childFactory._nextSibling;
            }

            // Mark the end of the initialization phase

            frameworkObject.EndInit();

            return frameworkObject;

        }
        // raise the SourceUpdatedEvent event (explicit polymorphism)
        internal static void OnSourceUpdated(DependencyObject d, DependencyProperty dp)
        {
            DataTransferEventArgs args = new DataTransferEventArgs(d, dp);
            args.RoutedEvent = Binding.SourceUpdatedEvent;
            FrameworkObject fo = new FrameworkObject(d);

            if (!fo.IsValid && d != null)
            {
                fo.Reset(Helper.FindMentor(d));
            }

            fo.RaiseEvent(args);
        }
        // Instantiate a tree.  This is a recursive routine that will build the
        //  subtree via calls to itself.  The root node being instantiated will
        //  have identical references for the "container" and "parent" parameters.
        // The "affectedChildren" and "noChildIndexChildren" parameters refer to the children
        //  chain for the "container" object.  This chain will have all the
        //  children - not just the immediate children.  The node being
        //  instantiated here will be added to this chain.
        // The tree is instantiated in a depth-first traversal, so children nodes
        //  are added to the chain in depth-first order as well.
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        internal DependencyObject InstantiateTree(
                UncommonField<HybridDictionary[]>           dataField,
                DependencyObject                            container,
                DependencyObject                            parent,
                List<DependencyObject>                      affectedChildren,
            ref List<DependencyObject>                      noChildIndexChildren,
            ref FrugalStructList<ChildPropertyDependent>    resourceDependents)
        {
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstBegin);

            FrameworkElement containerAsFE = container as FrameworkElement;
            bool isContainerAnFE = containerAsFE != null;

            DependencyObject treeNode = null;
            // If we have text, just add it to the parent.  Otherwise create the child
            // subtree
            if (_text != null)
            {
                // of FrameworkContentElement parent.  This is the logical equivalent
                // to what happens when adding a child to a visual collection.
                IAddChild addChildParent = parent as IAddChild;

                if (addChildParent == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.TypeMustImplementIAddChild,
                                                         parent.GetType().Name));
                }
                else
                {
                    addChildParent.AddText(_text);
                }
            }
            else
            {
                // Factory create instance
                treeNode = CreateDependencyObject();

                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstEnd);

                // The tree node is either a FrameworkElement or a FrameworkContentElement.
                //  we'll deal with one or the other...
                FrameworkObject treeNodeFO = new FrameworkObject(treeNode);

                Visual3D treeNodeVisual3D = null;
                bool treeNodeIsVisual3D = false;

                if (!treeNodeFO.IsValid)
                {
                    // If it's neither of those, we have special support for Visual3D

                    treeNodeVisual3D = treeNode as Visual3D;
                    if (treeNodeVisual3D != null)
                        treeNodeIsVisual3D = true;
                }

                Debug.Assert( treeNodeFO.IsValid || (treeNodeVisual3D != null),
                    "We should not be trying to instantiate a node that is neither FrameworkElement nor FrameworkContentElement.  A type check should have been done when Type is set");

                // And here's the bool we'll use to make the decision.
                bool treeNodeIsFE = treeNodeFO.IsFE;

                // Handle FE/FCE-specific optimizations

                if (!treeNodeIsVisual3D)
                {
                    // Postpone "Initialized" event
                    NewNodeBeginInit( treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );

                    // Set the resource reference flags
                    if (StyleHelper.HasResourceDependentsForChild(_childIndex, ref resourceDependents))
                    {
                        treeNodeFO.HasResourceReference = true;
                    }

                    // Update the two chains that tracks all the nodes created
                    //  from all the FrameworkElementFactory of this Style.
                    UpdateChildChains( _childName, _childIndex,
                        treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE,
                        affectedChildren, ref noChildIndexChildren );

                    // All FrameworkElementFactory-created elements point to the object
                    //  whose Style.VisualTree definition caused all this to occur
                    NewNodeStyledParentProperty( container, isContainerAnFE, treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );

                    // Initialize the per-instance data for the new element.  This
                    // needs to be done before any properties are invalidated.
                    if (_childIndex != -1)
                    {
                        Debug.Assert( _frameworkTemplate != null );

                        StyleHelper.CreateInstanceDataForChild(dataField, container, treeNode, _childIndex,
                            _frameworkTemplate.HasInstanceValues, ref _frameworkTemplate.ChildRecordFromChildIndex);
                    }

                    // If this element needs to know about the Loaded or Unloaded events, set the optimization
                    // bit in the element

                    if (HasLoadedChangeHandler)
                    {
                        BroadcastEventHelper.AddHasLoadedChangeHandlerFlagInAncestry(treeNode);
                    }
                }
                else
                {
                    if (_childName != null)
                    {
                        // Add this instance to the child index chain so that it may
                        // be tracked by the style

                        affectedChildren.Add(treeNode);
                    }
                    else
                    {
                        // Child nodes with no _childID (hence no _childIndex) are
                        //  tracked on a separate chain that will be appended to the
                        //  main chain for cleanup purposes.
                        if (noChildIndexChildren == null)
                        {
                            noChildIndexChildren = new List<DependencyObject>(4);
                        }

                        noChildIndexChildren.Add(treeNode);
                    }
                }


                // New node is initialized, build tree top down
                // (Node added before children of node)
                if (container == parent)
                {
                    // Set the NameScope on the root of the Template generated tree
                    TemplateNameScope templateNameScope = new TemplateNameScope(container);
                    NameScope.SetNameScope(treeNode, templateNameScope);

                    // This is the root of the tree
                    if (isContainerAnFE)
                    {
                        // The root is added to the Visual tree (not logical) for the
                        // case of FrameworkElement parents
                        containerAsFE.TemplateChild = treeNodeFO.FE;
                    }
                    else
                    {
                        // The root is added to the logical tree for the case
                        // of FrameworkContentElement parent.  This is the logical equivalent
                        // to what happens when adding a child to a visual collection.
                        AddNodeToLogicalTree( (FrameworkContentElement)parent, _type,
                            treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );
                    }
                }
                else
                {
                    // Call parent IAddChild to add treeNodeFO
                    AddNodeToParent( parent, treeNodeFO );
                }

                // Either set properties or invalidate them, depending on the type

                if (!treeNodeIsVisual3D)
                {
                    // For non-3D content, we need to invalidate any properties that
                    // came from FrameworkElementFactory.SetValue or VisulaTrigger.SetValue
                    // so that they can get picked up.

                    Debug.Assert( _frameworkTemplate != null );
                    StyleHelper.InvalidatePropertiesOnTemplateNode(
                                container,
                                treeNodeFO,
                                _childIndex,
                                ref _frameworkTemplate.ChildRecordFromChildIndex,
                                false /*isDetach*/,
                                this);

                }
                else
                {
                    // For 3D, which doesn't understand templates, we set the properties directly
                    // onto the newly-instantiated element.

                    for (int i = 0; i < PropertyValues.Count; i++)
                    {
                        if (PropertyValues[i].ValueType == PropertyValueType.Set)
                        {
                            // Get the value out of the table.
                            object o = PropertyValues[i].ValueInternal;


                            // If it's a freezable that can't be frozen, it's probably not sharable,
                            // so we make a copy of it.
                            Freezable freezableValue = o as Freezable;
                            if (freezableValue != null && !freezableValue.CanFreeze)
                            {
                                o = freezableValue.Clone();
                            }

                            // Or, if it's a markup extension, get the value
                            // to set on this property from the MarkupExtension itself.
                            MarkupExtension me = o as MarkupExtension;
                            if (me != null)
                            {
                                ProvideValueServiceProvider serviceProvider = new ProvideValueServiceProvider();
                                serviceProvider.SetData( treeNodeVisual3D, PropertyValues[i].Property );
                                o = me.ProvideValue( serviceProvider );
                            }

                            // Finally, set the value onto the object.
                            treeNodeVisual3D.SetValue(PropertyValues[i].Property, o);

                        }

                        else
                        {
                            // We don't support resource references, triggers, etc within the 3D content
                            throw new NotSupportedException(SR.Get(SRID.Template3DValueOnly, PropertyValues[i].Property) );

                        }

                    }
                }


                // Build child tree from factories
                FrameworkElementFactory childFactory = _firstChild;
                while (childFactory != null)
                {
                    childFactory.InstantiateTree(
                        dataField,
                        container,
                        treeNode,
                        affectedChildren,
                        ref noChildIndexChildren,
                        ref resourceDependents);

                    childFactory = childFactory._nextSibling;
                }

                if (!treeNodeIsVisual3D)
                {
                    // Fire "Initialized" event
                    NewNodeEndInit( treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );
                }
            }
            return treeNode;
        }
Example #17
0
 /// <summary>
 /// Find the element given name
 /// </summary>
 object INameScope.FindName(string name)
 {
     // _templatedParent is null if template.LoadContent() was responsible
     if (_templatedParent != null)
     {
         FrameworkObject fo = new FrameworkObject(_templatedParent);
         
         Debug.Assert(fo.IsFE);
         if (fo.IsFE)
         {
             return StyleHelper.FindNameInTemplateContent(fo.FE, name, fo.FE.TemplateInternal);
         }
         else
         {
             return null;
         }
     }
     else
     {
         if (_nameMap == null || name == null || name == String.Empty)
             return null;
         
         return _nameMap[name];
     }
 }
Example #18
0
        // Given a FrameworkElement and a name string, this routine will try to find
        //  a node with Name property set to the given name.  It will search all 
        //  the child logical tree nodes of the given starting element.
        // If the name string is null or an empty string, the given starting element 
        //  is returned. 
        // If the name is found on a FrameworkContentElement, an exception is thrown
        // If the name is not found attached to anything, an exception is thrown 
        internal static FrameworkElement FindNamedFrameworkElement( FrameworkElement startElement, string targetName )
        {
            FrameworkElement targetFE = null;
 
            if( targetName == null || targetName.Length == 0 )
            { 
                targetFE = startElement; 
            }
            else 
            {
                DependencyObject targetObject = null;

                targetObject = LogicalTreeHelper.FindLogicalNode( startElement, targetName ); 

                if( targetObject == null ) 
                { 
                    throw new ArgumentException( SR.Get(SRID.TargetNameNotFound, targetName));
                } 

                FrameworkObject fo = new FrameworkObject(targetObject);
                if( fo.IsFE )
                { 
                    targetFE = fo.FE;
                } 
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.NamedObjectMustBeFrameworkElement, targetName)); 
                }
            }

            return targetFE; 
        }
Example #19
0
        // Fetchs the specified childRecord for the given template.  Returns true if successful.
        internal static void GetTemplatedParentChildRecord( 
            DependencyObject templatedParent,
            int childIndex, 
            out ChildRecord childRecord, 
            out bool isChildRecordValid)
        { 
            FrameworkTemplate templatedParentTemplate = null;
            isChildRecordValid = false;
            childRecord = new ChildRecord();    // CS0177
 
            if (templatedParent != null)
            { 
                FrameworkObject foTemplatedParent = new FrameworkObject(templatedParent, true); 

                Debug.Assert( foTemplatedParent.IsFE ); 

                // This node is the result of a style expansion

                // Pick the owner for the VisualTree that generated this node 
                templatedParentTemplate = foTemplatedParent.FE.TemplateInternal;
 
                Debug.Assert(templatedParentTemplate != null , 
                    "If this node is the result of a VisualTree expansion then it should have a parent template");
 
                // Check if this Child Index is represented in FrameworkTemplate
                if (templatedParentTemplate != null && ((0 <= childIndex) && (childIndex < templatedParentTemplate.ChildRecordFromChildIndex.Count)))
                {
                    childRecord = templatedParentTemplate.ChildRecordFromChildIndex[childIndex]; 
                    isChildRecordValid = true;
                } 
 
            }
        } 
        internal static FrameworkObject GetContainingFrameworkElement(DependencyObject current)
        {
            FrameworkObject fo = new FrameworkObject(current);

            while (!fo.IsValid && fo.DO != null)
            {
                // The current object is neither a FrameworkElement nor a
                // FrameworkContentElement.  We will now walk the "core"
                // tree looking for one.
                Visual visual;
                Visual3D visual3D;
                ContentElement ce;

                if ((visual = fo.DO as Visual) != null)
                {
                    fo.Reset(VisualTreeHelper.GetParent(visual));
                }
                else if ((ce = fo.DO as ContentElement) != null)
                {
                    fo.Reset(ContentOperations.GetParent(ce));
                }
                else if ((visual3D = fo.DO as Visual3D) != null)
                {
                    fo.Reset(VisualTreeHelper.GetParent(visual3D));
                }
                else
                {
                    // The parent could be an application.
                    fo.Reset(null);
                }
            }

            return fo;
        }
Example #21
0
        // Search the parent chain for a [Data|Table]Template in a ResourceDictionary. 
        private static object FindTemplateResourceInTree(DependencyObject target, ArrayList keys, int exactMatch, ref int bestMatch)
        { 
            Debug.Assert(target != null, "Don't call FindTemplateResource with a null target object"); 

            ResourceDictionary table; 
            object resource = null;

            FrameworkObject fo = new FrameworkObject(target);
            Debug.Assert(fo.IsValid, "Don't call FindTemplateResource with a target object that is neither a FrameworkElement nor a FrameworkContentElement"); 

            while (fo.IsValid) 
            { 
                object candidate;
 
                // -------------------------------------------
                //  Lookup ResourceDictionary on the current instance
                // -------------------------------------------
 
                // Fetch the ResourceDictionary
                // for the given target element 
                table = GetInstanceResourceDictionary(fo.FE, fo.FCE); 
                if( table != null )
                { 
                    candidate = FindBestMatchInResourceDictionary( table, keys, exactMatch, ref bestMatch );
                    if (candidate != null)
                    {
                        resource = candidate; 
                        if (bestMatch < exactMatch)
                        { 
                            // Exact match found, stop here. 
                            return resource;
                        } 
                    }
                }

                // ------------------------------------------- 
                //  Lookup ResourceDictionary on the current instance's Style, if one exists.
                // ------------------------------------------- 
 
                table = GetStyleResourceDictionary(fo.FE, fo.FCE);
                if( table != null ) 
                {
                    candidate = FindBestMatchInResourceDictionary( table, keys, exactMatch, ref bestMatch );
                    if (candidate != null)
                    { 
                        resource = candidate;
                        if (bestMatch < exactMatch) 
                        { 
                            // Exact match found, stop here.
                            return resource; 
                        }
                    }
                }
 
                // -------------------------------------------
                //  Lookup ResourceDictionary on the current instance's Theme Style, if one exists. 
                // ------------------------------------------- 

                table = GetThemeStyleResourceDictionary(fo.FE, fo.FCE); 
                if( table != null )
                {
                    candidate = FindBestMatchInResourceDictionary( table, keys, exactMatch, ref bestMatch );
                    if (candidate != null) 
                    {
                        resource = candidate; 
                        if (bestMatch < exactMatch) 
                        {
                            // Exact match found, stop here. 
                            return resource;
                        }
                    }
                } 

                // ------------------------------------------- 
                //  Lookup ResourceDictionary on the current instance's Template, if one exists. 
                // -------------------------------------------
 
                table = GetTemplateResourceDictionary(fo.FE, fo.FCE);
                if( table != null )
                {
                    candidate = FindBestMatchInResourceDictionary( table, keys, exactMatch, ref bestMatch ); 
                    if (candidate != null)
                    { 
                        resource = candidate; 
                        if (bestMatch < exactMatch)
                        { 
                            // Exact match found, stop here.
                            return resource;
                        }
                    } 
                }
 
                // If the current element for resource lookup is marked such then abort 
                // lookup because resource lookup does not span tree boundaries
                if (fo.IsValid && TreeWalkHelper.SkipNext(fo.InheritanceBehavior)) 
                {
                    break;
                }
 
                // -------------------------------------------
                //  Find the next parent instance to lookup 
                // ------------------------------------------- 

                // Get Framework Parent 
                fo = fo.FrameworkParent;

                // If the next parent for resource lookup is marked such then abort
                // lookup because resource lookup does not span tree boundaries 
                if (fo.IsValid && TreeWalkHelper.SkipNext(fo.InheritanceBehavior))
                { 
                    break; 
                }
            } 

            return resource;
        }
        internal static bool IsEffectiveAncestor(DependencyObject d1, DependencyObject d2
#if TRACE_INHERITANCE_CONTEXT
                                , DependencyProperty dp
#endif
                                )
        {
#if TRACE_INHERITANCE_CONTEXT
            int depth = 0;
#endif
            for (   FrameworkObject fo = new FrameworkObject(d2);
                    fo.DO != null;
                    fo.Reset(fo.EffectiveParent))
            {
                if (fo.DO == d1)
                {
#if TRACE_INHERITANCE_CONTEXT
                    Log("{0} creates cycle at depth {1}", LogIC(d2, dp, d1), depth);
#endif
                    return true;
                }
#if TRACE_INHERITANCE_CONTEXT
                ++depth;
#endif
            }

            return false;
        }
Example #23
0
        /// <summary>
        ///     Process a resource change for the given DependencyObject. 
        ///     Return true if the DO has resource references.
        /// </summary> 
        internal static void OnResourcesChanged( 
            DependencyObject    d,
            ResourcesChangeInfo info, 
            bool raiseResourceChangedEvent)
        {
            Debug.Assert(d != null, "Must have non-null current node");
 
            bool containsTypeOfKey = info.Contains(d.DependencyObjectType.SystemType, true /*isImplicitStyleKey*/);
            bool isSystemResourcesChange = info.IsThemeChange; 
            bool isStyleResourcesChange = info.IsStyleResourcesChange; 
            bool isTemplateResourcesChange = info.IsTemplateResourcesChange;
            bool isContainer = (info.Container == d); 

            FrameworkObject fo = new FrameworkObject(d);

            // If a resource dictionary changed above this node then we need to 
            // synchronize the ShouldLookupImplicitStyles flag with respect to
            // our parent here. 
 
            if (info.IsResourceAddOperation || info.IsCatastrophicDictionaryChange)
            { 
                fo.SetShouldLookupImplicitStyles();
            }

            // Invalidate implicit and explicit resource 
            // references on current instance
            if (fo.IsFE) 
            { 
                // If this is a FrameworkElement
                FrameworkElement fe = fo.FE; 
                fe.HasStyleChanged = false; // detect style changes that arise from work done here
                fe.HasStyleInvalidated = false;
                fe.HasTemplateChanged = false; // detect template changes that arise from work done here
 
                if (fe.HasResourceReference)
                { 
 
                    // Invalidate explicit ResourceReference properties on the current instance.
                    // If the Style property comes from an implicit resource reference that 
                    // will be invalidated too.
                    InvalidateResourceReferences(fe, info);

                    // There is no need to invalidate the resources references on the 
                    // container object if this call is a result of a style/template
                    // change. This is because the style/template change would have 
                    // already invalidated all the container dependents and all the 
                    // resources references on the container would have been a part of it.
                    if ((!isStyleResourcesChange && !isTemplateResourcesChange ) || !isContainer) 
                    {
                        InvalidateStyleAndReferences(d, info, containsTypeOfKey);
                    }
                } 
                else if (containsTypeOfKey &&
                        (fe.HasImplicitStyleFromResources || fe.Style == FrameworkElement.StyleProperty.GetMetadata(fe.DependencyObjectType).DefaultValue)) 
                { 
                    // If The Style property on the given instance has been
                    // fetched by an implicit resource lookup then 
                    // it needs to be invalidated. Also we need to do this
                    // invalidation only if the dictionary/resources that is
                    // changing matches the implicit key used for the resource lookup.
 
                    // The StyleProperty does not need to be invalidated if this
                    // call is the result of a style change 
                    if (!isStyleResourcesChange || !isContainer) 
                    {
                        fe.UpdateStyleProperty(); 
                    }
                }

                // If there has been a Theme change then 
                // invalidate the ThemeStyleProperty
                if (isSystemResourcesChange) 
                { 
                    fe.UpdateThemeStyleProperty();
                } 

                // Raise the ResourcesChanged Event so that ResourceReferenceExpressions
                // on non-[FE/FCE] (example Freezables) listening for this can then update
                // their values 
                if (raiseResourceChangedEvent && fe.PotentiallyHasMentees)
                { 
                    fe.RaiseClrEvent(FrameworkElement.ResourcesChangedKey, new ResourcesChangedEventArgs(info)); 
                }
            } 
            else
            {
                // If this is a FrameworkContentElement
                FrameworkContentElement fce = fo.FCE; 
                fce.HasStyleChanged = false; // detect style changes that arise from work done here
                fce.HasStyleInvalidated = false; 
 
                if (fce.HasResourceReference)
                { 
                    // Invalidate explicit ResourceReference properties on the current instance.
                    // If the Style property comes from an implicit resource reference that
                    // will be invalidated too.
                    InvalidateResourceReferences(fce, info); 

                    // There is no need to invalidate the resources references on the 
                    // container object if this call is a result of a style/template 
                    // change. This is because the style/template change would have
                    // already invalidated all the container dependents and all the 
                    // resources references on the container would have been a part of it.
                    if ((!isStyleResourcesChange && !isTemplateResourcesChange ) || !isContainer)
                    {
                        InvalidateStyleAndReferences(d, info, containsTypeOfKey); 
                    }
                } 
                else if (containsTypeOfKey && 
                        (fce.HasImplicitStyleFromResources || fce.Style == FrameworkContentElement.StyleProperty.GetMetadata(fce.DependencyObjectType).DefaultValue))
                { 
                    // If The Style property on the given instance has been
                    // fetched by an implicit resource lookup then
                    // it needs to be invalidated. Also we need to do this
                    // invalidation only if the dictionary/resources that is 
                    // changing matches the implicit key used for the resource lookup.
 
                    // The StyleProperty does not need to be invalidated if this 
                    // call is the result of a style change
                    if (!isStyleResourcesChange || !isContainer) 
                    {
                        fce.UpdateStyleProperty();
                    }
                } 

                // If there has been a Theme change then 
                // invalidate the ThemeStyleProperty 
                if (isSystemResourcesChange)
                { 
                    fce.UpdateThemeStyleProperty();
                }

                // Raise the ResourcesChanged Event so that ResourceReferenceExpressions 
                // on non-[FE/FCE] (example Freezables) listening for this can then update
                // their values 
                if (raiseResourceChangedEvent && fce.PotentiallyHasMentees) 
                {
                    fce.RaiseClrEvent(FrameworkElement.ResourcesChangedKey, new ResourcesChangedEventArgs(info)); 
                }
            }
        }
Example #24
0
        /// <summary>
        ///     Callback on visiting each node in the descendency during a tree change 
        ///     Note that this is only used in an entire sub-tree undergoes a change.
        ///     If the tree change is happening on a single node with no children, this 
        ///     invalidation happens inside InvalidateOnTreeChange and this method doesn't 
        ///     get involved.
        /// </summary> 
        private static bool OnAncestorChanged(
            DependencyObject d,
            TreeChangeInfo   info)
        { 
            // Invalidate properties on current instance
            FrameworkObject fo = new FrameworkObject(d, true); 
 
            OnAncestorChanged(fo.FE, fo.FCE, info);
 
            // Continue walk down subtree
            return true;
        }
Example #25
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); 
            }
        } 
Example #26
0
        /// <summary> 
        ///     Invalidate this property if 
        ///     - It is not locally set and
        ///     - It is not acquired from a style/template 
        /// </summary>
        private static bool InvalidateTreeDependentProperty(
            TreeChangeInfo              info,
            DependencyObject            d, 
        ref FrameworkObject             fo,
            DependencyProperty          dp, 
            FrameworkPropertyMetadata   fMetadata, 
            Style                       selfStyle,
            Style                       selfThemeStyle, 
            ref ChildRecord             childRecord,
            bool                        isChildRecordValid,
            bool                        hasStyleChanged,
            bool                        isSelfInheritanceParent) 
        {
            Debug.Assert(d != null, "Must have non-null current node"); 
 
            // This must be an inherited dependency property
            Debug.Assert(fMetadata.IsInherited == true, "This must be an inherited dependency property"); 

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

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

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

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

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

            return false;
        }
Example #27
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);
     }
 } 
Example #28
0
        /// <summary> 
        ///     Invalidates all the properties on the nodes in the given sub-tree
        ///     that are referring to the resource[s] that are changing.
        /// </summary>
        internal static void InvalidateOnResourcesChange( 
            FrameworkElement        fe,
            FrameworkContentElement fce, 
            ResourcesChangeInfo     info) 
        {
            Debug.Assert(fe != null || fce != null, "Node with the resources change notification must be an FE or an FCE."); 

            // We're interested in changes to the Template property that occur during
            // the walk - if the template has changed we don't need to invalidate
            // template-driven properties a second time.  The HasTemplateChanged property 
            // is cleared on the first visit to each node, so that it means "template
            // changed during the walk".  But one relevant node isn't visited during 
            // the walk - the templated parent of the initial node.  So we handle that now. 
            FrameworkObject fo = new FrameworkObject(fe, fce);
 
            fo.Reset(fo.TemplatedParent);
            fo.HasTemplateChanged = false;

            DependencyObject d = (fe != null) ? (DependencyObject)fe : (DependencyObject)fce; 

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

                DescendentsWalker<ResourcesChangeInfo> walker = new DescendentsWalker<ResourcesChangeInfo>(
                    TreeWalkPriority.LogicalTree, ResourcesChangeDelegate, info);
 
                walker.StartWalk(d);
            } 
            else 
            {
                // Degenerate case when the current node is a leaf node and has no children. 

                OnResourcesChanged(d, info, true);
            }
        } 
Example #29
0
        //
        // Get the closest Framework type up the logical or physical tree 
        //
        // (Shared between FrameworkElement and FrameworkContentElement)
        //
        internal static DependencyObject GetFrameworkParent(object current) 
        {
            FrameworkObject fo = new FrameworkObject(current as DependencyObject); 
 
            fo = fo.FrameworkParent;
 
            return fo.DO;
        }
Example #30
0
        /// <summary>
        ///     Invalidates all properties that reference a resource and are set via a style/template.
        /// </summary> 
        /// <remarks>
        ///     This methods is called when one of the following operations occurred. 
        ///     1) A resource dictionary change 
        ///     2) A modification to a single entry in a dictionary
        /// </remarks> 
        private static void InvalidateStyleAndReferences(
            DependencyObject    d,
            ResourcesChangeInfo info,
            bool                containsTypeOfKey) 
        {
            Debug.Assert(d != null, "Must have non-null current node"); 
 
            FrameworkObject fo = new FrameworkObject(d);
 
            if (fo.IsFE)
            {
                FrameworkElement fe = fo.FE;
 
                if (containsTypeOfKey &&
                    !info.IsThemeChange && 
                    (fe.HasImplicitStyleFromResources || fe.Style == FrameworkElement.StyleProperty.GetMetadata(fe.DependencyObjectType).DefaultValue)) 
                {
                    // If The Style property on the given instance has been 
                    // fetched by an implicit resource lookup then
                    // it needs to be invalidated. Also we need to do this
                    // invalidation only if the dictionary/resources that is
                    // changing matches the implicit key used for the resource lookup. 
                    // If we invalidate the style then we do not need to
                    // InvalidateResourceDependents because applying an 
                    // all new style will have the same effect 
                    fe.UpdateStyleProperty();
                } 
                else if (fe.Style != null && fe.Style.HasResourceReferences)
                {
                    // Check for resource references contained within associated Style.
                    // If found, invalidate all properties that are being driven by a resource. 
                    // If the style has changed recently, that change would have already
                    // invalidated these properties. 
                    if (!fe.HasStyleChanged) 
                    {
                        StyleHelper.InvalidateResourceDependents(d, info, ref fe.Style.ResourceDependents, 
                            false /* invalidateVisualTreeToo */);
                    }
                }
 
                if (fe.TemplateInternal != null && fe.TemplateInternal.HasContainerResourceReferences)
                { 
                    // Check for resource references contained within associated Template. 
                    // If found, invalidate all properties that are being driven by a resource
                    StyleHelper.InvalidateResourceDependents(d, info, ref fe.TemplateInternal.ResourceDependents, 
                        false /* invalidateVisualTreeToo */);
                }

                if (fe.TemplateChildIndex > 0) 
                {
                    // Check for resource references contained within parent's Template. 
                    // If found, invalidate all properties that are being driven by a resource 
                    FrameworkElement templatedParent = (FrameworkElement)fe.TemplatedParent;
                    FrameworkTemplate parentTemplate = templatedParent.TemplateInternal; 

                    if (!templatedParent.HasTemplateChanged && parentTemplate.HasChildResourceReferences)
                    {
                        StyleHelper.InvalidateResourceDependentsForChild( 
                                            templatedParent,
                                            fe, 
                                            fe.TemplateChildIndex, 
                                            info,
                                            parentTemplate); 
                    }
                }

 
                if (!info.IsThemeChange)
                { 
                    // Invalidate ResourceReferences on ThemeStyle only if this insn't a Theme change. 
                    // It it is then ThemeStyle would already have been invalidated and hence there isn't
                    // a need to duplicate it here. 
                    Style themeStyle = fe.ThemeStyle;
                    if (themeStyle != null && themeStyle.HasResourceReferences)
                    {
                        if (themeStyle != fe.Style) 
                        {
                            StyleHelper.InvalidateResourceDependents(d, info, ref themeStyle.ResourceDependents, 
                                false /* invalidateVisualTreeToo */); 
                        }
                    } 
                }
            }
            else if (fo.IsFCE)
            { 
                FrameworkContentElement fce = fo.FCE;
 
                if (containsTypeOfKey && 
                    !info.IsThemeChange &&
                    (fce.HasImplicitStyleFromResources || fce.Style == FrameworkContentElement.StyleProperty.GetMetadata(fce.DependencyObjectType).DefaultValue)) 
                {
                    // If The Style property on the given instance has been
                    // fetched by an implicit resource lookup then
                    // it needs to be invalidated. Also we need to do this 
                    // invalidation only if the dictionary/resources that is
                    // changing matches the implicit key used for the resource lookup. 
                    // If we invalidate the style then we do not need to 
                    // InvalidateResourceDependents because applying an
                    // all new style will have the same effect 
                    fce.UpdateStyleProperty();
                }
                else if (fce.Style != null && fce.Style.HasResourceReferences)
                { 
                    // Check for resource references contained within associated Style.
                    // If found, invalidate all properties that are being driven by a resource 
                    // If the style has changed recently, that change would have already 
                    // invalidated these properties.
                    if (!fce.HasStyleChanged) 
                    {
                        StyleHelper.InvalidateResourceDependents(d, info, ref fce.Style.ResourceDependents, !
                            false /*invalidateVisualTreeToo */);
                    } 
                }
 
 
                if (fce.TemplateChildIndex > 0)
                { 
                    // Check for resource references contained within parent's Template.
                    // If found, invalidate all properties that are being driven by a resource
                    FrameworkElement templatedParent = (FrameworkElement)fce.TemplatedParent;
                    FrameworkTemplate parentTemplate = templatedParent.TemplateInternal; 

                    if (!templatedParent.HasTemplateChanged && parentTemplate.HasChildResourceReferences) 
                    { 
                        StyleHelper.InvalidateResourceDependentsForChild(
                                            templatedParent, 
                                            fce,
                                            fce.TemplateChildIndex,
                                            info,
                                            parentTemplate); 
                    }
                } 
 
                if (!info.IsThemeChange)
                { 
                    // Invalidate ResourceReferences on ThemeStyle only if this insn't a Theme change.
                    // It it is then ThemeStyle would already have been invalidated and hence there isn't
                    // a need to duplicate it here.
                    Style themeStyle = fce.ThemeStyle; 
                    if (themeStyle != null && themeStyle.HasResourceReferences)
                    { 
                        if (themeStyle != fce.Style) 
                        {
                            StyleHelper.InvalidateResourceDependents(d, info, ref themeStyle.ResourceDependents, 
                                false /*invalidateVisualTreeToo */);
                        }
                    }
                } 
            }
        } 
Example #31
0
        private DependencyObject FindAncestorOfType(Type type, int level, DependencyObject d, bool isTracing)
        { 
            if (type == null) 
            {
                if (TraceData.IsEnabled) 
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorTypeNotSpecified);
                return null;
            }
            if (level < 1) 
            {
                if (TraceData.IsEnabled) 
                    TraceData.Trace(TraceEventType.Error, TraceData.RefAncestorLevelInvalid); 
                return null;
            } 

            // initialize search to start at the parent of the given DO
            FrameworkObject fo = new FrameworkObject(d);
            fo.Reset(fo.GetPreferVisualParent(true).DO); 

            while (fo.DO != null) 
            { 
                if (isTracing)
                { 
                    TraceData.Trace(TraceEventType.Warning,
                                        TraceData.AncestorLookup(
                                            type.Name,
                                            TraceData.Identify(fo.DO))); 
                }
 
                if (type.IsInstanceOfType(fo.DO))   // found it! 
                {
                    if (--level <= 0) 
                        break;
                }

                fo.Reset(fo.PreferVisualParent.DO); 
            }
 
            return fo.DO; 
        }
Example #32
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);
        } 
Example #33
0
        private void InvalidatePropertiesOnTemplate(DependencyObject container, Object currentObject)
        {
            if (container != null)
            {
                DependencyObject dObject = currentObject as DependencyObject;
                if (dObject != null)
                {
                    FrameworkObject child = new FrameworkObject(dObject);
                    if (child.IsValid)
                    {
                        int templateChildIndex = child.TemplateChildIndex;

                        // the template may have resource references for this child
                        if (StyleHelper.HasResourceDependentsForChild(templateChildIndex, ref this.ResourceDependents))
                        {
                            child.HasResourceReference = true;
                        }

                        // Invalidate properties on the element that come from the template.

                        StyleHelper.InvalidatePropertiesOnTemplateNode(container,
                            child, templateChildIndex, ref this.ChildRecordFromChildIndex, false, this.VisualTree);
                    }

                }
            }
        }
        //
        //  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;
        }
Example #35
0
        // FindResourceInternal(fe/fce)  Defaults: none
        internal static object FindResourceInternal( 
            FrameworkElement        fe, 
            FrameworkContentElement fce,
            DependencyProperty      dp, 
            object                  resourceKey,
            object                  unlinkedParent,
            bool                    allowDeferredResourceReference,
            bool                    mustReturnDeferredResourceReference, 
            DependencyObject        boundaryElement,
            bool                    isImplicitStyleLookup, 
            out object              source) 
        {
            object value; 
            InheritanceBehavior inheritanceBehavior = InheritanceBehavior.Default;

            if( TraceResourceDictionary.IsEnabled )
            { 
                FrameworkObject element = new FrameworkObject(fe, fce);
 
                TraceResourceDictionary.Trace( 
                    TraceEventType.Start,
                    TraceResourceDictionary.FindResource, 
                     element.DO,
                     resourceKey );
            }
 
            try
            { 
 
                // First try to find the resource in the tree
                if (fe != null || fce != null || unlinkedParent != null) 
                {
                    value = FindResourceInTree(fe, fce, dp, resourceKey, unlinkedParent, allowDeferredResourceReference, mustReturnDeferredResourceReference, boundaryElement,
                                                out inheritanceBehavior, out source);
                    if (value != DependencyProperty.UnsetValue) 
                    {
                        return value; 
                    } 

                } 

                // Then we try to find the resource in the App's Resources
                Application app = Application.Current;
                if (app != null && 
                    (inheritanceBehavior == InheritanceBehavior.Default ||
                     inheritanceBehavior == InheritanceBehavior.SkipToAppNow || 
                     inheritanceBehavior == InheritanceBehavior.SkipToAppNext)) 
                {
                    value = app.FindResourceInternal(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference); 
                    if (value != null)
                    {
                        source = app;
 
                        if( TraceResourceDictionary.IsEnabled )
                        { 
                            TraceResourceDictionary.TraceActivityItem( 
                                TraceResourceDictionary.FoundResourceInApplication,
                                 resourceKey, 
                                value );
                        }

                        return value; 
                    }
                } 
 
                // Then we try to find the resource in the SystemResources but that is only if we aren't
                // doing an implicit style lookup. Implicit style lookup will stop at the app. 
                if (!isImplicitStyleLookup &&
                    inheritanceBehavior != InheritanceBehavior.SkipAllNow &&
                    inheritanceBehavior != InheritanceBehavior.SkipAllNext)
                { 
                    value = SystemResources.FindResourceInternal(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference);
                    if (value != null) 
                    { 
                        source = SystemResourceHost.Instance;
 
                        if( TraceResourceDictionary.IsEnabled )
                        {
                            TraceResourceDictionary.TraceActivityItem(
                                TraceResourceDictionary.FoundResourceInTheme, 
                                source,
                                resourceKey, 
                                value ); 
                        }
 

                        return value;
                    }
                } 
            }
            finally 
            { 
                if( TraceResourceDictionary.IsEnabled )
                { 
                    FrameworkObject element = new FrameworkObject(fe, fce);

                    TraceResourceDictionary.Trace(
                        TraceEventType.Stop, 
                        TraceResourceDictionary.FindResource,
                         element.DO, 
                         resourceKey ); 
                }
            } 

            // We haven't found the resource.  Trace a message to the debugger.
            //
            // Only trace if this isn't an implicit 
            // style lookup and the element has been loaded
            if (TraceResourceDictionary.IsEnabledOverride && !isImplicitStyleLookup) 
            { 
                if ((fe != null && fe.IsLoaded) || (fce != null && fce.IsLoaded))
                { 
                    TraceResourceDictionary.Trace( TraceEventType.Warning,
                            TraceResourceDictionary.ResourceNotFound,
                            resourceKey );
                } 
                else if( TraceResourceDictionary.IsEnabled )
                { 
                    TraceResourceDictionary.TraceActivityItem( 
                            TraceResourceDictionary.ResourceNotFound,
                            resourceKey ); 
                }
            }

            source = null; 
            return DependencyProperty.UnsetValue;
        }