Example #1
0
        // Token: 0x06000C6A RID: 3178 RVA: 0x0002E850 File Offset: 0x0002CA50
        private static void InvalidateResourceReferences(DependencyObject d, ResourcesChangeInfo info)
        {
            LocalValueEnumerator localValueEnumerator = d.GetLocalValueEnumerator();
            int count = localValueEnumerator.Count;

            if (count > 0)
            {
                ResourceReferenceExpression[] array = new ResourceReferenceExpression[count];
                int num = 0;
                while (localValueEnumerator.MoveNext())
                {
                    LocalValueEntry             localValueEntry             = localValueEnumerator.Current;
                    ResourceReferenceExpression resourceReferenceExpression = localValueEntry.Value as ResourceReferenceExpression;
                    if (resourceReferenceExpression != null && info.Contains(resourceReferenceExpression.ResourceKey, false))
                    {
                        array[num] = resourceReferenceExpression;
                        num++;
                    }
                }
                ResourcesChangedEventArgs e = new ResourcesChangedEventArgs(info);
                for (int i = 0; i < num; i++)
                {
                    array[i].InvalidateExpressionValue(d, e);
                }
            }
        }
Example #2
0
        /// <summary>
        ///     Invalidates all properties that reference a resource. 
        ///     NOTE: The return value for this method indicates whether or not a ResourceReference 
        ///     property was found on the given object. This is to take care of the special case when
        ///     programmatically changing a ResourceReference property value does not reflect on the 
        ///     bit stored on FrameworkElement or FrameworkContentElement that indicates whether
        ///     the current instance has ResourceReference values set on it. This current operation
        ///     is a point of synchronization for this flag.
        /// </summary> 
        /// <remarks>
        ///     This methods is called when one of the following operations occurred. 
        ///     1) A tree change 
        ///     2) A resource dictionary change
        ///     3) A modification to a single entry in a dictionary 
        /// </remarks>
        private static void InvalidateResourceReferences(
            DependencyObject    d,
            ResourcesChangeInfo info) 
        {
            Debug.Assert(d != null, "Must have non-null current node"); 
 
            // Find properties that have resource reference value
            LocalValueEnumerator localValues = d.GetLocalValueEnumerator(); 
            int localValuesCount = localValues.Count;

            if (localValuesCount > 0)
            { 
                // Resource reference invalidation involves two passes - first to
                // pick out what we need to invalidate, and the second to do the 
                // actual invalidation.  This is needed because LocalValueEnumerator 
                // will halt if any local values have changed, which can happen
                // depending on what people are doing in their OnPropertyChanged 
                // callback.

                // The following array is used to track the ResourceReferenceExpressions that we find
                ResourceReferenceExpression[] resources = new ResourceReferenceExpression[localValuesCount]; 
                int invalidationCount = 0;
 
                // Pass #1 - find what needs invalidation 
                while (localValues.MoveNext())
                { 
                    // Is this a resource reference?
                    ResourceReferenceExpression resource = localValues.Current.Value as ResourceReferenceExpression;
                    if (resource != null)
                    { 
                        // Record this property if it is referring
                        // to a resource that is being changed 
                        if (info.Contains(resource.ResourceKey, false /*isImplicitStyleKey*/)) 
                        {
                            resources[invalidationCount]  = resource; 
                            invalidationCount++;
                        }
                    }
                } 

                ResourcesChangedEventArgs args = new ResourcesChangedEventArgs(info); 
 
                // Pass #2 - actually make the invalidation calls, now that we're
                // outside the LocalValueEnumerator. 
                for (int i = 0; i < invalidationCount; i++)
                {
                    // Let the resource reference throw away its cache
                    // and invalidate the property in which it's held 
                    // re-evaluate expression
                    resources[i].InvalidateExpressionValue(d, args); 
                } 
            }
        } 
Example #3
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 #4
0
        // Token: 0x06000C69 RID: 3177 RVA: 0x0002E674 File Offset: 0x0002C874
        internal static void OnResourcesChanged(DependencyObject d, ResourcesChangeInfo info, bool raiseResourceChangedEvent)
        {
            bool            flag                      = info.Contains(d.DependencyObjectType.SystemType, true);
            bool            isThemeChange             = info.IsThemeChange;
            bool            isStyleResourcesChange    = info.IsStyleResourcesChange;
            bool            isTemplateResourcesChange = info.IsTemplateResourcesChange;
            bool            flag2                     = info.Container == d;
            FrameworkObject frameworkObject           = new FrameworkObject(d);

            if (info.IsResourceAddOperation || info.IsCatastrophicDictionaryChange)
            {
                frameworkObject.SetShouldLookupImplicitStyles();
            }
            if (frameworkObject.IsFE)
            {
                FrameworkElement fe = frameworkObject.FE;
                fe.HasStyleChanged     = false;
                fe.HasStyleInvalidated = false;
                fe.HasTemplateChanged  = false;
                if (info.IsImplicitDataTemplateChange)
                {
                    ContentPresenter contentPresenter = fe as ContentPresenter;
                    if (contentPresenter != null)
                    {
                        contentPresenter.ReevaluateTemplate();
                    }
                }
                if (fe.HasResourceReference)
                {
                    TreeWalkHelper.InvalidateResourceReferences(fe, info);
                    if ((!isStyleResourcesChange && !isTemplateResourcesChange) || !flag2)
                    {
                        TreeWalkHelper.InvalidateStyleAndReferences(d, info, flag);
                    }
                }
                else if (flag && (fe.HasImplicitStyleFromResources || fe.Style == FrameworkElement.StyleProperty.GetMetadata(fe.DependencyObjectType).DefaultValue) && (!isStyleResourcesChange || !flag2))
                {
                    fe.UpdateStyleProperty();
                }
                if (isThemeChange)
                {
                    fe.UpdateThemeStyleProperty();
                }
                if (raiseResourceChangedEvent && fe.PotentiallyHasMentees)
                {
                    fe.RaiseClrEvent(FrameworkElement.ResourcesChangedKey, new ResourcesChangedEventArgs(info));
                    return;
                }
            }
            else
            {
                FrameworkContentElement fce = frameworkObject.FCE;
                fce.HasStyleChanged     = false;
                fce.HasStyleInvalidated = false;
                if (fce.HasResourceReference)
                {
                    TreeWalkHelper.InvalidateResourceReferences(fce, info);
                    if ((!isStyleResourcesChange && !isTemplateResourcesChange) || !flag2)
                    {
                        TreeWalkHelper.InvalidateStyleAndReferences(d, info, flag);
                    }
                }
                else if (flag && (fce.HasImplicitStyleFromResources || fce.Style == FrameworkContentElement.StyleProperty.GetMetadata(fce.DependencyObjectType).DefaultValue) && (!isStyleResourcesChange || !flag2))
                {
                    fce.UpdateStyleProperty();
                }
                if (isThemeChange)
                {
                    fce.UpdateThemeStyleProperty();
                }
                if (raiseResourceChangedEvent && fce.PotentiallyHasMentees)
                {
                    fce.RaiseClrEvent(FrameworkElement.ResourcesChangedKey, new ResourcesChangedEventArgs(info));
                }
            }
        }
        //
        //  This method
        //  1. Invalidates all the resource references set on a template for a given child.
        //  2. Returns true if any were found
        //
        internal static void InvalidateResourceDependentsForChild(
                DependencyObject                            container,
                DependencyObject                            child,
                int                                         childIndex,
                ResourcesChangeInfo                         info,
                FrameworkTemplate                           parentTemplate)
        {
            FrugalStructList<ChildPropertyDependent> resourceDependents = parentTemplate.ResourceDependents;
            int count = resourceDependents.Count;

            // Invalidate all properties on the given child that
            // are being driven via a resource reference in a template
            for (int i = 0; i < count; i++)
            {
                if (resourceDependents[i].ChildIndex == childIndex &&
                    info.Contains(resourceDependents[i].Name, false /*isImplicitStyleKey*/))
                {
                    DependencyProperty dp = resourceDependents[i].Property;
                    // Update property on child
                    child.InvalidateProperty(dp);

                    // skip remaining dependents for the same property - we only
                    // need to invalidate once.  The list is sorted, so we just need
                    // to skip until we find a new property.
                    int dpIndex = dp.GlobalIndex;
                    while (++i < resourceDependents.Count)
                    {
                        if (resourceDependents[i].ChildIndex != childIndex ||
                            resourceDependents[i].Property.GlobalIndex != dpIndex)
                        {
                            break;
                        }
                    }
                    --i;    // back up to let the for-loop do its normal increment
                }
            }
        }
        //
        //  This method
        //  1. Invalidates all the resource references set on a style or a template.
        //
        //  Note: In the case that the visualtree was not generated from the particular
        //  style in question we will skip past those resource references that haven't
        //  been set on the container. This condition is described by the
        //  invalidateVisualTreeToo flag being false.
        //
        internal static void InvalidateResourceDependents(
            DependencyObject                             container,
            ResourcesChangeInfo                          info,
            ref FrugalStructList<ChildPropertyDependent> resourceDependents,
            bool                                         invalidateVisualTreeToo)
        {
            List<DependencyObject> styledChildren = TemplatedFeChildrenField.GetValue(container);

            // Invalidate all properties on this container and its children that
            // are being driven via a resource reference in a style
            for (int i = 0; i < resourceDependents.Count; i++)
            {
                // Invalidate property
                //  1. If nothing is known about the data or
                //  2. If the data tells us the key in the dictionary that was modified and this property is refering to it or
                //  3. If it tells us info about the changed dictionaries and this property was refering to one of their entries
                //  4. If this a theme change
                if (info.Contains(resourceDependents[i].Name, false /*isImplicitStyleKey*/))
                {
                    DependencyObject child = null;
                    DependencyProperty invalidProperty = resourceDependents[i].Property;

                    int childIndex = resourceDependents[i].ChildIndex;
                    if (childIndex == 0)
                    {
                        // Index '0' means 'self' (container)
                        child = container;
                    }
                    else if (invalidateVisualTreeToo)
                    {
                        Debug.Assert(styledChildren != null, "Should reach here only if the template tree has already been created");

                        // Locate child to invalidate
                        child = GetChild(styledChildren, childIndex);

                        if (child == null)
                        {
                            throw new InvalidOperationException(SR.Get(SRID.ChildTemplateInstanceDoesNotExist));
                        }
                    }

                    if (child != null)
                    {
                        // Invalidate property on child
                        child.InvalidateProperty(invalidProperty);

                        // skip remaining dependents for the same property - we only
                        // need to invalidate once.  The list is sorted, so we just need
                        // to skip until we find a new property.
                        int dpIndex = invalidProperty.GlobalIndex;
                        while (++i < resourceDependents.Count)
                        {
                            if (resourceDependents[i].ChildIndex != childIndex ||
                                resourceDependents[i].Property.GlobalIndex != dpIndex)
                            {
                                break;
                            }
                        }
                        --i;    // back up to let the for-loop do its normal increment
                    }
                }
            }
        }