예제 #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);
                }
            }
        }
        /// <summary>
        ///     This event handler is called to invalidate the cached value held in
        ///     this expression. This is called under the following 3 scenarios
        ///     1. InheritanceContext changes
        ///     2. Logical tree changes
        ///     3. ResourceDictionary changes
        /// </summary>
        internal void InvalidateExpressionValue(object sender, EventArgs e)
        {
            // VS has a scenario where a TreeWalk invalidates all reference expressions on a DependencyObject.
            // If there is a dependency between RRE's,
            // invalidating one RRE could cause _targetObject to be null on the other RRE. Hence this check.
            if (_targetObject == null)
            {
                return;
            }

            ResourcesChangedEventArgs args = e as ResourcesChangedEventArgs;

            if (args != null)
            {
                ResourcesChangeInfo info = args.Info;
                if (!info.IsTreeChange)
                {
                    // This will happen when
                    // 1. Theme changes
                    // 2. Entire ResourceDictionary in the ancestry changes
                    // 3. Single entry in a ResourceDictionary in the ancestry is changed
                    // In all of the above cases it is sufficient to re-evaluate the cache
                    // value alone. The mentor relation ships stay the same.
                    InvalidateCacheValue();
                }
                else
                {
                    // This is the case of a logical tree change and hence we need to
                    // re-evaluate both the mentor and the cached value.
                    InvalidateMentorCache();
                }
            }
            else
            {
                // There is no information provided by the EventArgs. Hence we
                // pessimistically invalidate both the mentor and the cached value.
                // This code path will execute when the InheritanceContext changes.
                InvalidateMentorCache();
            }

            InvalidateTargetProperty(sender, e);
        }
예제 #3
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);
            }
        } 
예제 #4
0
 internal ResourcesChangedEventArgs(ResourcesChangeInfo info)
 {
     _info = info;
 }
예제 #5
0
        // Token: 0x06000C6B RID: 3179 RVA: 0x0002E8E0 File Offset: 0x0002CAE0
        private static void InvalidateStyleAndReferences(DependencyObject d, ResourcesChangeInfo info, bool containsTypeOfKey)
        {
            FrameworkObject frameworkObject = new FrameworkObject(d);

            if (frameworkObject.IsFE)
            {
                FrameworkElement fe = frameworkObject.FE;
                if (containsTypeOfKey && !info.IsThemeChange && (fe.HasImplicitStyleFromResources || fe.Style == FrameworkElement.StyleProperty.GetMetadata(fe.DependencyObjectType).DefaultValue))
                {
                    fe.UpdateStyleProperty();
                }
                if (fe.Style != null && fe.Style.HasResourceReferences && !fe.HasStyleChanged)
                {
                    StyleHelper.InvalidateResourceDependents(d, info, ref fe.Style.ResourceDependents, false);
                }
                if (fe.TemplateInternal != null && fe.TemplateInternal.HasContainerResourceReferences)
                {
                    StyleHelper.InvalidateResourceDependents(d, info, ref fe.TemplateInternal.ResourceDependents, false);
                }
                if (fe.TemplateChildIndex > 0)
                {
                    FrameworkElement  frameworkElement = (FrameworkElement)fe.TemplatedParent;
                    FrameworkTemplate templateInternal = frameworkElement.TemplateInternal;
                    if (!frameworkElement.HasTemplateChanged && templateInternal.HasChildResourceReferences)
                    {
                        StyleHelper.InvalidateResourceDependentsForChild(frameworkElement, fe, fe.TemplateChildIndex, info, templateInternal);
                    }
                }
                if (!info.IsThemeChange)
                {
                    Style themeStyle = fe.ThemeStyle;
                    if (themeStyle != null && themeStyle.HasResourceReferences && themeStyle != fe.Style)
                    {
                        StyleHelper.InvalidateResourceDependents(d, info, ref themeStyle.ResourceDependents, false);
                        return;
                    }
                }
            }
            else if (frameworkObject.IsFCE)
            {
                FrameworkContentElement fce = frameworkObject.FCE;
                if (containsTypeOfKey && !info.IsThemeChange && (fce.HasImplicitStyleFromResources || fce.Style == FrameworkContentElement.StyleProperty.GetMetadata(fce.DependencyObjectType).DefaultValue))
                {
                    fce.UpdateStyleProperty();
                }
                if (fce.Style != null && fce.Style.HasResourceReferences && !fce.HasStyleChanged)
                {
                    StyleHelper.InvalidateResourceDependents(d, info, ref fce.Style.ResourceDependents, true);
                }
                if (fce.TemplateChildIndex > 0)
                {
                    FrameworkElement  frameworkElement2 = (FrameworkElement)fce.TemplatedParent;
                    FrameworkTemplate templateInternal2 = frameworkElement2.TemplateInternal;
                    if (!frameworkElement2.HasTemplateChanged && templateInternal2.HasChildResourceReferences)
                    {
                        StyleHelper.InvalidateResourceDependentsForChild(frameworkElement2, fce, fce.TemplateChildIndex, info, templateInternal2);
                    }
                }
                if (!info.IsThemeChange)
                {
                    Style themeStyle2 = fce.ThemeStyle;
                    if (themeStyle2 != null && themeStyle2.HasResourceReferences && themeStyle2 != fce.Style)
                    {
                        StyleHelper.InvalidateResourceDependents(d, info, ref themeStyle2.ResourceDependents, false);
                    }
                }
            }
        }
예제 #6
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));
                }
            }
        }
예제 #7
0
        //
        //  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
                }
            }
        }
예제 #8
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); 
                } 
            }
        } 
예제 #9
0
        private void InvalidateResourceReferenceOnWindowCollection(WindowCollection wc, ResourcesChangeInfo info)
        {
            bool hasImplicitStyles  = info.IsResourceAddOperation && HasImplicitStylesInResources;

            for (int i = 0; i < wc.Count; i++)
            {
                // calling thread is the same as the wc[i] thread so synchronously invalidate
                // resouces, else, post a dispatcher workitem to invalidate resources.
                if (wc[i].CheckAccess() == true)
                {
                    // Set the ShouldLookupImplicitStyles flag on the App's windows
                    // to true if App.Resources has implicit styles.

                    if (hasImplicitStyles)
                        wc[i].ShouldLookupImplicitStyles = true;

                    TreeWalkHelper.InvalidateOnResourcesChange(wc[i], null, info);
                }
                else
                {
                    wc[i].Dispatcher.BeginInvoke(
                        DispatcherPriority.Send,
                        (DispatcherOperationCallback) delegate(object obj)
                        {
                            object[] args = obj as object[];

                            // Set the ShouldLookupImplicitStyles flag on the App's windows
                            // to true if App.Resources has implicit styles.

                            if (hasImplicitStyles)
                                ((FrameworkElement)args[0]).ShouldLookupImplicitStyles = true;

                            TreeWalkHelper.InvalidateOnResourcesChange((FrameworkElement)args[0], null, (ResourcesChangeInfo)args[1]);
                            return null;
                        },
                        new object[] {wc[i], info}
                        );
                }
            }
        }
예제 #10
0
 internal void InvalidateResourceReferences(ResourcesChangeInfo info)
 {
     // Invalidate ResourceReference properties on all the windows.
     // we Clone() the collection b/c if we don't then some other thread can be
     // modifying the collection while we iterate over it
     InvalidateResourceReferenceOnWindowCollection(WindowsInternal.Clone(), info);
     InvalidateResourceReferenceOnWindowCollection(NonAppWindowsInternal.Clone(), info);
 }
 internal ResourcesChangedEventArgs(ResourcesChangeInfo info)
 {
     _info = info;
 }
예제 #12
0
        /// <summary>
        /// Called when the MergedDictionaries collection changes
        /// </summary>
        /// <param name="sender"></param> 
        /// <param name="e"></param>
        private void OnMergedDictionariesChanged(object sender, NotifyCollectionChangedEventArgs e) 
        { 
            List<ResourceDictionary> oldDictionaries = null;
            List<ResourceDictionary> newDictionaries = null; 
            ResourceDictionary mergedDictionary;
            ResourcesChangeInfo info;

            if (e.Action != NotifyCollectionChangedAction.Reset) 
            {
                Invariant.Assert( 
                    (e.NewItems != null && e.NewItems.Count > 0) || 
                    (e.OldItems != null && e.OldItems.Count > 0),
                    "The NotifyCollectionChanged event fired when no dictionaries were added or removed"); 


                // If one or more resource dictionaries were removed we
                // need to remove the owners they were given by their 
                // parent ResourceDictionary.
 
                if (e.Action == NotifyCollectionChangedAction.Remove 
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    oldDictionaries = new List<ResourceDictionary>(e.OldItems.Count);

                    for (int i = 0; i < e.OldItems.Count; i++)
                    { 
                        mergedDictionary = (ResourceDictionary)e.OldItems[i];
                        oldDictionaries.Add(mergedDictionary); 
 
                        RemoveParentOwners(mergedDictionary);
                    } 
                }

                // If one or more resource dictionaries were added to the merged
                // dictionaries collection we need to send down the parent 
                // ResourceDictionary's owners.
 
                if (e.Action == NotifyCollectionChangedAction.Add 
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    newDictionaries = new List<ResourceDictionary>(e.NewItems.Count);

                    for (int i = 0; i < e.NewItems.Count; i++)
                    { 
                        mergedDictionary = (ResourceDictionary)e.NewItems[i];
                        newDictionaries.Add(mergedDictionary); 
 
                        // If the merged dictionary HasImplicitStyle mark the outer dictionary the same.
                        if (!HasImplicitStyles && mergedDictionary.HasImplicitStyles) 
                        {
                            HasImplicitStyles = true;
                        }
 
                        // If the parent dictionary is a theme dictionary mark the merged dictionary the same.
                        if (IsThemeDictionary) 
                        { 
                            mergedDictionary.IsThemeDictionary = true;
                        } 

                        PropagateParentOwners(mergedDictionary);
                    }
                } 

                info = new ResourcesChangeInfo(oldDictionaries, newDictionaries, false, false, null); 
            } 
            else
            { 
                // Case when MergedDictionary collection is cleared
                info = ResourcesChangeInfo.CatastrophicDictionaryChangeInfo;
            }
 
            // Notify the owners of the change and fire
            // invalidation if already initialized 
 
            NotifyOwners(info);
        } 
예제 #13
0
        // Call FrameworkElement.InvalidateTree with the right data
        private void NotifyOwners(ResourcesChangeInfo info)
        {
            bool shouldInvalidate   = IsInitialized; 
            bool hasImplicitStyles  = info.IsResourceAddOperation && HasImplicitStyles;
 
            if (shouldInvalidate || hasImplicitStyles) 
            {
                // Invalidate all FE owners 
                if (_ownerFEs != null)
                {
                    foreach (Object o in _ownerFEs)
                    { 
                        FrameworkElement fe = o as FrameworkElement;
                        if (fe != null) 
                        { 
                            // Set the HasImplicitStyles flag on the owner
                            if (hasImplicitStyles) 
                                fe.ShouldLookupImplicitStyles = true;

                            // If this dictionary has been initialized fire an invalidation
                            // to let the tree know of this change. 
                            if (shouldInvalidate)
                                TreeWalkHelper.InvalidateOnResourcesChange(fe, null, info); 
                        } 
                    }
                } 

                // Invalidate all FCE owners
                if (_ownerFCEs != null)
                { 
                    foreach (Object o in _ownerFCEs)
                    { 
                        FrameworkContentElement fce = o as FrameworkContentElement; 
                        if (fce != null)
                        { 
                            // Set the HasImplicitStyles flag on the owner
                            if (hasImplicitStyles)
                                fce.ShouldLookupImplicitStyles = true;
 
                            // If this dictionary has been initialized fire an invalidation
                            // to let the tree know of this change. 
                            if (shouldInvalidate) 
                                TreeWalkHelper.InvalidateOnResourcesChange(null, fce, info);
                        } 
                    }
                }

                // Invalidate all App owners 
                if (_ownerApps != null)
                { 
                    foreach (Object o in _ownerApps) 
                    {
                        Application app = o as Application; 
                        if (app != null)
                        {
                            // Set the HasImplicitStyles flag on the owner
                            if (hasImplicitStyles) 
                                app.HasImplicitStylesInResources = true;
 
                            // If this dictionary has been initialized fire an invalidation 
                            // to let the tree know of this change.
                            if (shouldInvalidate) 
                                app.InvalidateResourceReferences(info);
                        }
                    }
                } 
            }
        } 
예제 #14
0
        /// <summary> 
        ///     Callback on visiting each node in the descendency 
        ///     during a resources change.
        /// </summary> 
        private static bool OnResourcesChangedCallback(
            DependencyObject    d,
            ResourcesChangeInfo info)
        { 
            OnResourcesChanged(d, info, true);
 
            // Continue walk down subtree 
            return true;
        } 
예제 #15
0
        // Token: 0x06000C67 RID: 3175 RVA: 0x0002E60C File Offset: 0x0002C80C
        internal static void InvalidateOnResourcesChange(FrameworkElement fe, FrameworkContentElement fce, ResourcesChangeInfo info)
        {
            FrameworkObject frameworkObject = new FrameworkObject(fe, fce);

            frameworkObject.Reset(frameworkObject.TemplatedParent);
            frameworkObject.HasTemplateChanged = false;
            DependencyObject dependencyObject = (fe != null) ? fe : fce;

            if (TreeWalkHelper.HasChildren(fe, fce))
            {
                DescendentsWalker <ResourcesChangeInfo> descendentsWalker = new DescendentsWalker <ResourcesChangeInfo>(TreeWalkPriority.LogicalTree, TreeWalkHelper.ResourcesChangeDelegate, info);
                descendentsWalker.StartWalk(dependencyObject);
                return;
            }
            TreeWalkHelper.OnResourcesChanged(dependencyObject, info, true);
        }
예제 #16
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)); 
                }
            }
        }
예제 #17
0
 // Token: 0x06000C68 RID: 3176 RVA: 0x0002E666 File Offset: 0x0002C866
 private static bool OnResourcesChangedCallback(DependencyObject d, ResourcesChangeInfo info, bool visitedViaVisualTree)
 {
     TreeWalkHelper.OnResourcesChanged(d, info, true);
     return(true);
 }
예제 #18
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 */);
                        }
                    }
                } 
            }
        } 
예제 #19
0
        //
        //  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
                    }
                }
            }
        }