// Token: 0x06000C6E RID: 3182 RVA: 0x0002ECD4 File Offset: 0x0002CED4 internal static void OnInheritedPropertyChanged(DependencyObject d, ref InheritablePropertyChangeInfo info, InheritanceBehavior inheritanceBehavior) { if (inheritanceBehavior == InheritanceBehavior.Default || TreeWalkHelper.IsForceInheritedProperty(info.Property)) { FrameworkObject frameworkObject = new FrameworkObject(d); frameworkObject.OnInheritedPropertyChanged(ref info); } }
// Token: 0x06000C66 RID: 3174 RVA: 0x0002E490 File Offset: 0x0002C690 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, bool wasSelfInheritanceParent) { if (!TreeWalkHelper.SkipNext(fo.InheritanceBehavior) || fMetadata.OverridesInheritanceBehavior) { InheritablePropertyChangeInfo rootInheritableValue = info.GetRootInheritableValue(dp); EffectiveValueEntry oldEntry = rootInheritableValue.OldEntry; EffectiveValueEntry effectiveValueEntry = info.IsAddOperation ? rootInheritableValue.NewEntry : new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited); bool flag = TreeWalkHelper.IsForceInheritedProperty(dp); if (d != info.Root) { if (wasSelfInheritanceParent) { oldEntry = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences); } else if (isSelfInheritanceParent) { EffectiveValueEntry valueEntry = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences); if (valueEntry.BaseValueSourceInternal <= BaseValueSourceInternal.Inherited) { oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved); oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } else { oldEntry = valueEntry; } } else { oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved); oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } } else if (info.IsAddOperation && (flag || oldEntry.BaseValueSourceInternal <= BaseValueSourceInternal.Inherited)) { EffectiveValueEntry valueEntry2 = d.GetValueEntry(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, RequestFlags.DeferredReferences); if (valueEntry2.BaseValueSourceInternal > BaseValueSourceInternal.Inherited) { oldEntry = valueEntry2; } } OperationType operationType = info.IsAddOperation ? OperationType.AddChild : OperationType.RemoveChild; if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal) { return((d.UpdateEffectiveValue(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, oldEntry, ref effectiveValueEntry, false, false, operationType) & (UpdateResult)5) == UpdateResult.ValueChanged); } if (flag) { effectiveValueEntry = new EffectiveValueEntry(dp, FullValueSource.IsCoerced); return((d.UpdateEffectiveValue(d.LookupEntry(dp.GlobalIndex), dp, fMetadata, oldEntry, ref effectiveValueEntry, false, false, operationType) & (UpdateResult)5) == UpdateResult.ValueChanged); } } return(false); }
// Helper method to retrieve and fire the InheritedPropertyChanged event internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info) { EventHandlersStore store = EventHandlersStore; if (store != null) { Delegate handler = store.Get(FrameworkElement.InheritedPropertyChangedKey); if (handler != null) { InheritedPropertyChangedEventArgs args = new InheritedPropertyChangedEventArgs(ref info); ((InheritedPropertyChangedEventHandler)handler)(this, args); } } }
// 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); } }
/// <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); }
/// <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); } }
internal void OnInheritedPropertyChanged(ref InheritablePropertyChangeInfo info) { if (IsFE) { _fe.RaiseInheritedPropertyChangedEvent(ref info); } else if (IsFCE) { _fce.RaiseInheritedPropertyChangedEvent(ref info); } }
/// <summary> /// Notification that a specified property has been changed /// </summary> /// <param name="e">EventArgs that contains the property, metadata, old value, and new value for this change</param> protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { DependencyProperty dp = e.Property; base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { // // Try to fire the Loaded event on the root of the tree // because for this case the OnParentChanged will not // have a chance to fire the Loaded event. // if (dp != null && dp.OwnerType == typeof(PresentationSource) && dp.Name == "RootSource") { TryFireInitialized(); } if (dp == FrameworkElement.NameProperty && EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose)) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.PerfElementIDName, EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose, PerfService.GetPerfElementID(this), GetType().Name, GetValue(dp)); } // // Invalidation propagation for Styles // // Regardless of metadata, the Style/DefaultStyleKey properties are never a trigger drivers if (dp != StyleProperty && dp != DefaultStyleKeyProperty) { // Note even properties on non-container nodes within a template could be driving a trigger if (TemplatedParent != null) { FrameworkElement feTemplatedParent = TemplatedParent as FrameworkElement; FrameworkTemplate frameworkTemplate = feTemplatedParent.TemplateInternal; StyleHelper.OnTriggerSourcePropertyInvalidated(null, frameworkTemplate, TemplatedParent, dp, e, false /*invalidateOnlyContainer*/, ref frameworkTemplate.TriggerSourceRecordFromChildIndex, ref frameworkTemplate.PropertyTriggersWithActions, TemplateChildIndex /*sourceChildIndex*/); } // Do not validate Style during an invalidation if the Style was // never used before (dependents do not need invalidation) if (Style != null) { StyleHelper.OnTriggerSourcePropertyInvalidated(Style, null, this, dp, e, true /*invalidateOnlyContainer*/, ref Style.TriggerSourceRecordFromChildIndex, ref Style.PropertyTriggersWithActions, 0 /*sourceChildId*/); // Style can only have triggers that are driven by properties on the container } // Do not validate Template during an invalidation if the Template was // never used before (dependents do not need invalidation) // There may be container dependents in the ThemeStyle. Invalidate them. if (ThemeStyle != null && Style != ThemeStyle) { StyleHelper.OnTriggerSourcePropertyInvalidated(ThemeStyle, null, this, dp, e, true /*invalidateOnlyContainer*/, ref ThemeStyle.TriggerSourceRecordFromChildIndex, ref ThemeStyle.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // ThemeStyle can only have triggers that are driven by properties on the container } } } FrameworkPropertyMetadata fmetadata = e.Metadata as FrameworkPropertyMetadata; // // Invalidation propagation for Groups and Inheritance // // Metadata must exist specifically stating propagate invalidation // due to group or inheritance if (fmetadata != null) { // // Inheritance // if (fmetadata.Inherits) { // Invalidate Inheritable descendents only if instance is not a TreeSeparator // or fmetadata.OverridesInheritanceBehavior is set to override separated tree behavior if ((InheritanceBehavior == InheritanceBehavior.Default || fmetadata.OverridesInheritanceBehavior) && (!DependencyObject.IsTreeWalkOperation(e.OperationType) || PotentiallyHasMentees)) { EffectiveValueEntry newEntry = e.NewEntry; EffectiveValueEntry oldEntry = e.OldEntry; if (oldEntry.BaseValueSourceInternal > newEntry.BaseValueSourceInternal) { // valuesource == Inherited && value == UnsetValue indicates that we are clearing the inherited value newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited); } else { newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved); newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } if (oldEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default || oldEntry.HasModifiers) { oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved); oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } else { // we use an empty EffectiveValueEntry as a signal that the old entry was the default value oldEntry = new EffectiveValueEntry(); } InheritablePropertyChangeInfo info = new InheritablePropertyChangeInfo( dp, oldEntry, newEntry); // Don't InvalidateTree if we're in the middle of doing it. if (!DependencyObject.IsTreeWalkOperation(e.OperationType)) { TreeWalkHelper.InvalidateOnInheritablePropertyChange(null, this, info, true); } // Notify mentees if they exist if (PotentiallyHasMentees) { TreeWalkHelper.OnInheritedPropertyChanged(this, ref info, InheritanceBehavior); } } } } }
// Helper method to retrieve and fire the InheritedPropertyChanged event internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info) { EventHandlersStore store = EventHandlersStore; if (store != null) { Delegate handler = store.Get(FrameworkElement.InheritedPropertyChangedKey); if (handler != null) { InheritedPropertyChangedEventArgs args = new InheritedPropertyChangedEventArgs(ref info); ((InheritedPropertyChangedEventHandler)handler)(this, args); } } }
// Token: 0x06000C6C RID: 3180 RVA: 0x0002EB1C File Offset: 0x0002CD1C internal static void InvalidateOnInheritablePropertyChange(FrameworkElement fe, FrameworkContentElement fce, InheritablePropertyChangeInfo info, bool skipStartNode) { DependencyProperty property = info.Property; FrameworkObject frameworkObject = new FrameworkObject(fe, fce); if (TreeWalkHelper.HasChildren(fe, fce)) { DependencyObject @do = frameworkObject.DO; DescendentsWalker <InheritablePropertyChangeInfo> descendentsWalker = new DescendentsWalker <InheritablePropertyChangeInfo>(TreeWalkPriority.LogicalTree, TreeWalkHelper.InheritablePropertyChangeDelegate, info); descendentsWalker.StartWalk(@do, skipStartNode); return; } if (!skipStartNode) { bool visitedViaVisualTree = false; TreeWalkHelper.OnInheritablePropertyChanged(frameworkObject.DO, info, visitedViaVisualTree); } }
// // 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); }
/// <summary> /// Notification that a specified property has been changed /// </summary> /// <param name="e">EventArgs that contains the property, metadata, old value, and new value for this change</param> protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { DependencyProperty dp = e.Property; base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { // // Try to fire the Loaded event on the root of the tree // because for this case the OnParentChanged will not // have a chance to fire the Loaded event. // if (dp != null && dp.OwnerType == typeof(PresentationSource) && dp.Name == "RootSource") { TryFireInitialized(); } if (dp == FrameworkElement.NameProperty && EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose)) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.PerfElementIDName, EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose, PerfService.GetPerfElementID(this), GetType().Name, GetValue(dp)); } // // Invalidation propagation for Styles // // Regardless of metadata, the Style/Template/DefaultStyleKey properties are never a trigger drivers if (dp != StyleProperty && dp != Control.TemplateProperty && dp != DefaultStyleKeyProperty) { // Note even properties on non-container nodes within a template could be driving a trigger if (TemplatedParent != null) { FrameworkElement feTemplatedParent = TemplatedParent as FrameworkElement; FrameworkTemplate frameworkTemplate = feTemplatedParent.TemplateInternal; StyleHelper.OnTriggerSourcePropertyInvalidated(null, frameworkTemplate, TemplatedParent, dp, e, false /*invalidateOnlyContainer*/, ref frameworkTemplate.TriggerSourceRecordFromChildIndex, ref frameworkTemplate.PropertyTriggersWithActions, TemplateChildIndex /*sourceChildIndex*/); } // Do not validate Style during an invalidation if the Style was // never used before (dependents do not need invalidation) if (Style != null) { StyleHelper.OnTriggerSourcePropertyInvalidated(Style, null, this, dp, e, true /*invalidateOnlyContainer*/, ref Style.TriggerSourceRecordFromChildIndex, ref Style.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // Style can only have triggers that are driven by properties on the container } // Do not validate Template during an invalidation if the Template was // never used before (dependents do not need invalidation) if (TemplateInternal != null) { StyleHelper.OnTriggerSourcePropertyInvalidated(null, TemplateInternal, this, dp, e, !HasTemplateGeneratedSubTree /*invalidateOnlyContainer*/, ref TemplateInternal.TriggerSourceRecordFromChildIndex, ref TemplateInternal.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // These are driven by the container } // There may be container dependents in the ThemeStyle. Invalidate them. if (ThemeStyle != null && Style != ThemeStyle) { StyleHelper.OnTriggerSourcePropertyInvalidated(ThemeStyle, null, this, dp, e, true /*invalidateOnlyContainer*/, ref ThemeStyle.TriggerSourceRecordFromChildIndex, ref ThemeStyle.PropertyTriggersWithActions, 0 /*sourceChildIndex*/); // ThemeStyle can only have triggers that are driven by properties on the container } } } FrameworkPropertyMetadata fmetadata = e.Metadata as FrameworkPropertyMetadata; // // Invalidation propagation for Groups and Inheritance // // Metadata must exist specifically stating propagate invalidation // due to group or inheritance if (fmetadata != null) { // // Inheritance // if (fmetadata.Inherits) { // Invalidate Inheritable descendents only if instance is not a TreeSeparator // or fmetadata.OverridesInheritanceBehavior is set to override separated tree behavior if ((InheritanceBehavior == InheritanceBehavior.Default || fmetadata.OverridesInheritanceBehavior) && (!DependencyObject.IsTreeWalkOperation(e.OperationType) || PotentiallyHasMentees)) { EffectiveValueEntry newEntry = e.NewEntry; EffectiveValueEntry oldEntry = e.OldEntry; if (oldEntry.BaseValueSourceInternal > newEntry.BaseValueSourceInternal) { // valuesource == Inherited && value == UnsetValue indicates that we are clearing the inherited value newEntry = new EffectiveValueEntry(dp, BaseValueSourceInternal.Inherited); } else { newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved); newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } if (oldEntry.BaseValueSourceInternal != BaseValueSourceInternal.Default || oldEntry.HasModifiers) { oldEntry = oldEntry.GetFlattenedEntry(RequestFlags.FullyResolved); oldEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } else { // we use an empty EffectiveValueEntry as a signal that the old entry was the default value oldEntry = new EffectiveValueEntry(); } InheritablePropertyChangeInfo info = new InheritablePropertyChangeInfo( dp, oldEntry, newEntry); // Don't InvalidateTree if we're in the middle of doing it. if (!DependencyObject.IsTreeWalkOperation(e.OperationType)) { TreeWalkHelper.InvalidateOnInheritablePropertyChange(this, null, info, true); } // Notify mentees if they exist if (PotentiallyHasMentees) { TreeWalkHelper.OnInheritedPropertyChanged(this, ref info, InheritanceBehavior); } } } if (e.IsAValueChange || e.IsASubPropertyChange) { // // Layout invalidation // // Skip if we're traversing an Visibility=Collapsed subtree while // in the middle of an invalidation storm due to ancestor change if( !(AncestorChangeInProgress && InVisibilityCollapsedTree) ) { UIElement layoutParent = null; bool affectsParentMeasure = fmetadata.AffectsParentMeasure; bool affectsParentArrange = fmetadata.AffectsParentArrange; bool affectsMeasure = fmetadata.AffectsMeasure; bool affectsArrange = fmetadata.AffectsArrange; if (affectsMeasure || affectsArrange || affectsParentArrange || affectsParentMeasure) { // Locate nearest Layout parent for (Visual v = VisualTreeHelper.GetParent(this) as Visual; v != null; v = VisualTreeHelper.GetParent(v) as Visual) { layoutParent = v as UIElement; if (layoutParent != null) { //let incrementally-updating FrameworkElements to mark the vicinity of the affected child //to perform partial update. if(FrameworkElement.DType.IsInstanceOfType(layoutParent)) ((FrameworkElement)layoutParent).ParentLayoutInvalidated(this); if (affectsParentMeasure) { layoutParent.InvalidateMeasure(); } if (affectsParentArrange) { layoutParent.InvalidateArrange(); } break; } } } if (fmetadata.AffectsMeasure) { // if (!BypassLayoutPolicies || !((dp == WidthProperty) || (dp == HeightProperty))) { InvalidateMeasure(); } } if (fmetadata.AffectsArrange) { InvalidateArrange(); } if (fmetadata.AffectsRender && (e.IsAValueChange || !fmetadata.SubPropertiesDoNotAffectRender)) { InvalidateVisual(); } } } } }
internal InheritedPropertyChangedEventArgs(ref InheritablePropertyChangeInfo info) { _info = info; }
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { DependencyProperty property = e.Property; base.OnPropertyChanged(e); if (e.IsAValueChange || e.IsASubPropertyChange) { if (property != null && property.OwnerType == typeof (PresentationSource) && property.Name == "RootSource") this.TryFireInitialized(); if (property == FrameworkElement.NameProperty && EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose)) { int num = (int) EventTrace.EventProvider.TraceEvent(EventTrace.Event.PerfElementIDName, EventTrace.Keyword.KeywordGeneral, EventTrace.Level.Verbose, (object) PerfService.GetPerfElementID((object) this), (object) this.GetType().Name, this.GetValue(property)); } if (property != FrameworkElement.StyleProperty && property != Control.TemplateProperty && property != FrameworkElement.DefaultStyleKeyProperty) { if (this.TemplatedParent != null) { FrameworkTemplate templateInternal = (this.TemplatedParent as FrameworkElement).TemplateInternal; StyleHelper.OnTriggerSourcePropertyInvalidated((Style) null, templateInternal, this.TemplatedParent, property, e, false, ref templateInternal.TriggerSourceRecordFromChildIndex, ref templateInternal.PropertyTriggersWithActions, this.TemplateChildIndex); } if (this.Style != null) StyleHelper.OnTriggerSourcePropertyInvalidated(this.Style, (FrameworkTemplate) null, (DependencyObject) this, property, e, true, ref this.Style.TriggerSourceRecordFromChildIndex, ref this.Style.PropertyTriggersWithActions, 0); if (this.TemplateInternal != null) StyleHelper.OnTriggerSourcePropertyInvalidated((Style) null, this.TemplateInternal, (DependencyObject) this, property, e, !this.HasTemplateGeneratedSubTree, ref this.TemplateInternal.TriggerSourceRecordFromChildIndex, ref this.TemplateInternal.PropertyTriggersWithActions, 0); if (this.ThemeStyle != null && this.Style != this.ThemeStyle) StyleHelper.OnTriggerSourcePropertyInvalidated(this.ThemeStyle, (FrameworkTemplate) null, (DependencyObject) this, property, e, true, ref this.ThemeStyle.TriggerSourceRecordFromChildIndex, ref this.ThemeStyle.PropertyTriggersWithActions, 0); } } FrameworkPropertyMetadata propertyMetadata = e.Metadata as FrameworkPropertyMetadata; if (propertyMetadata == null) return; if (propertyMetadata.Inherits && (this.InheritanceBehavior == InheritanceBehavior.Default || propertyMetadata.OverridesInheritanceBehavior) && (!DependencyObject.IsTreeWalkOperation(e.OperationType) || this.PotentiallyHasMentees)) { EffectiveValueEntry newEntry = e.NewEntry; EffectiveValueEntry oldEntry1 = e.OldEntry; if (oldEntry1.BaseValueSourceInternal > newEntry.BaseValueSourceInternal) { newEntry = new EffectiveValueEntry(property, BaseValueSourceInternal.Inherited); } else { newEntry = newEntry.GetFlattenedEntry(RequestFlags.FullyResolved); newEntry.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } EffectiveValueEntry oldEntry2; if (oldEntry1.BaseValueSourceInternal != BaseValueSourceInternal.Default || oldEntry1.HasModifiers) { oldEntry2 = oldEntry1.GetFlattenedEntry(RequestFlags.FullyResolved); oldEntry2.BaseValueSourceInternal = BaseValueSourceInternal.Inherited; } else oldEntry2 = new EffectiveValueEntry(); InheritablePropertyChangeInfo info = new InheritablePropertyChangeInfo((DependencyObject) this, property, oldEntry2, newEntry); if (!DependencyObject.IsTreeWalkOperation(e.OperationType)) TreeWalkHelper.InvalidateOnInheritablePropertyChange(this, (FrameworkContentElement) null, info, true); if (this.PotentiallyHasMentees) TreeWalkHelper.OnInheritedPropertyChanged((DependencyObject) this, ref info, this.InheritanceBehavior); } if (!e.IsAValueChange && !e.IsASubPropertyChange || this.AncestorChangeInProgress && this.InVisibilityCollapsedTree) return; bool affectsParentMeasure = propertyMetadata.AffectsParentMeasure; bool affectsParentArrange = propertyMetadata.AffectsParentArrange; if (propertyMetadata.AffectsMeasure || propertyMetadata.AffectsArrange || (affectsParentArrange || affectsParentMeasure)) { for (Visual visual = VisualTreeHelper.GetParent((DependencyObject) this) as Visual; visual != null; visual = VisualTreeHelper.GetParent((DependencyObject) visual) as Visual) { UIElement uiElement = visual as UIElement; if (uiElement != null) { if (FrameworkElement.DType.IsInstanceOfType((DependencyObject) uiElement)) ((FrameworkElement) uiElement).ParentLayoutInvalidated((UIElement) this); if (affectsParentMeasure) uiElement.InvalidateMeasure(); if (affectsParentArrange) { uiElement.InvalidateArrange(); break; } else break; } } } if (propertyMetadata.AffectsMeasure && (!this.BypassLayoutPolicies || property != FrameworkElement.WidthProperty && property != FrameworkElement.HeightProperty)) this.InvalidateMeasure(); if (propertyMetadata.AffectsArrange) this.InvalidateArrange(); if (!propertyMetadata.AffectsRender || !e.IsAValueChange && propertyMetadata.SubPropertiesDoNotAffectRender) return; this.InvalidateVisual(); }
internal void RaiseInheritedPropertyChangedEvent(ref InheritablePropertyChangeInfo info) { EventHandlersStore eventHandlersStore = this.EventHandlersStore; if (eventHandlersStore == null) return; Delegate @delegate = eventHandlersStore.Get(FrameworkElement.InheritedPropertyChangedKey); if (@delegate == null) return; InheritedPropertyChangedEventArgs e = new InheritedPropertyChangedEventArgs(ref info); ((InheritedPropertyChangedEventHandler) @delegate)((object) this, e); }
// // 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; }
// Token: 0x06000C6D RID: 3181 RVA: 0x0002EB78 File Offset: 0x0002CD78 private static bool OnInheritablePropertyChanged(DependencyObject d, InheritablePropertyChangeInfo info, bool visitedViaVisualTree) { DependencyProperty property = info.Property; EffectiveValueEntry oldEntry = info.OldEntry; EffectiveValueEntry newEntry = info.NewEntry; InheritanceBehavior inheritanceBehavior; bool flag = TreeWalkHelper.IsInheritanceNode(d, property, out inheritanceBehavior); bool flag2 = TreeWalkHelper.IsForceInheritedProperty(property); if (!flag || (TreeWalkHelper.SkipNext(inheritanceBehavior) && !flag2)) { return(inheritanceBehavior == InheritanceBehavior.Default || flag2); } PropertyMetadata metadata = property.GetMetadata(d); EntryIndex entryIndex = d.LookupEntry(property.GlobalIndex); if (!d.IsSelfInheritanceParent) { DependencyObject frameworkParent = FrameworkElement.GetFrameworkParent(d); InheritanceBehavior inheritanceBehavior2 = InheritanceBehavior.Default; if (frameworkParent != null) { FrameworkObject frameworkObject = new FrameworkObject(frameworkParent, true); inheritanceBehavior2 = frameworkObject.InheritanceBehavior; } if (!TreeWalkHelper.SkipNext(inheritanceBehavior) && !TreeWalkHelper.SkipNow(inheritanceBehavior2)) { d.SynchronizeInheritanceParent(frameworkParent); } if (oldEntry.BaseValueSourceInternal == BaseValueSourceInternal.Unknown) { oldEntry = EffectiveValueEntry.CreateDefaultValueEntry(property, metadata.GetDefaultValue(d, property)); } } else { oldEntry = d.GetValueEntry(entryIndex, property, metadata, RequestFlags.RawEntry); } if (BaseValueSourceInternal.Inherited >= oldEntry.BaseValueSourceInternal) { if (visitedViaVisualTree && FrameworkElement.DType.IsInstanceOfType(d)) { DependencyObject parent = LogicalTreeHelper.GetParent(d); if (parent != null) { DependencyObject parent2 = VisualTreeHelper.GetParent(d); if (parent2 != null && parent2 != parent) { return(false); } } } return((d.UpdateEffectiveValue(entryIndex, property, metadata, oldEntry, ref newEntry, false, false, OperationType.Inherit) & (UpdateResult)5) == UpdateResult.ValueChanged); } if (flag2) { newEntry = new EffectiveValueEntry(property, FullValueSource.IsCoerced); return((d.UpdateEffectiveValue(d.LookupEntry(property.GlobalIndex), property, metadata, oldEntry, ref newEntry, false, false, OperationType.Inherit) & (UpdateResult)5) == UpdateResult.ValueChanged); } return(false); }
/// <summary> /// Callback on visiting each node in the descendency /// during an inheritable property change /// </summary> private static bool OnInheritablePropertyChanged( DependencyObject d, InheritablePropertyChangeInfo info, bool visitedViaVisualTree) { 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) { if (visitedViaVisualTree && FrameworkElement.DType.IsInstanceOfType(d)) { DependencyObject logicalParent = LogicalTreeHelper.GetParent(d); if (logicalParent != null) { DependencyObject visualParent = VisualTreeHelper.GetParent(d); if (visualParent != null && visualParent != logicalParent) { // Consider the following logical tree configuration. In this case we want // to RibbonToggleButton to pick up the new DataContext flowing in from // the Window. // // Window (info.RootElement) // ... // RibbonGroup (IsCollapsed) // RibbonControl (only in visual tree) // RibbonToggleButton // // Consider the following logical tree configuration. In this case we do not // want to RibbonToggleButton to change its DataContext because the changes // are only within the visual tree. // // Window // ... // RibbonGroup (IsCollapsed) // RibbonControl (only in visual tree) (info.RootElement) // RibbonToggleButton // // Saying it another way, the RibbonToggleButton in the above case belongs in a // different logical tree than the one that the current invalidation storm begun. // // Any change in an inheritable property begins an invalidation storm using the // DescendentsWalker and configures it to first traverse the logical children // and then visual children. Also nodes that have previously been visited via the // logical tree do not get visited again through the visual tree. I use this very // behavior as the basis for detecting nodes such as RibbonToggleButton. If the // RibbonToggleButton is being visisted for the first time via the visual tree then // the invalidation storm did not include its logical parent. And therefore the // RibbonToggleButton can early out of this storm. return false; } } } // 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); }