// 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> /// 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); } } }
/// <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)); } } }
// 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 } } } }