// Token: 0x06004CF1 RID: 19697 RVA: 0x0015AE9C File Offset: 0x0015909C internal void OnThemeChanged() { if (this.Header != null) { DependencyObject dependencyObject = this.Header as DependencyObject; if (dependencyObject != null) { FrameworkElement frameworkElement; FrameworkContentElement frameworkContentElement; Helper.DowncastToFEorFCE(dependencyObject, out frameworkElement, out frameworkContentElement, false); if (frameworkElement != null || frameworkContentElement != null) { TreeWalkHelper.InvalidateOnResourcesChange(frameworkElement, frameworkContentElement, ResourcesChangeInfo.ThemeChangeInfo); } } } }
//------------------------------------------------------------------- // // Internal Methodes // //------------------------------------------------------------------- #region Internal Methodes // Propagate theme changes to contained headers internal void OnThemeChanged() { if (Header != null) { DependencyObject d = Header as DependencyObject; if (d != null) { FrameworkElement fe; FrameworkContentElement fce; Helper.DowncastToFEorFCE(d, out fe, out fce, false); if (fe != null || fce != null) { TreeWalkHelper.InvalidateOnResourcesChange(fe, fce, ResourcesChangeInfo.ThemeChangeInfo); } } } }
private static bool UpdateEffectiveValue(INTERNAL_PropertyStorage storage, object newValue, BaseValueSourceInternal newValueSource, bool coerceWithCurrentValue, bool coerceValue, bool clearValue, bool propagateChanges) { global::System.Diagnostics.Debug.Assert((coerceWithCurrentValue == coerceValue && !coerceValue) || coerceValue != coerceWithCurrentValue); bool isCoerceOperation = coerceValue || coerceWithCurrentValue; BaseValueSourceInternal oldBaseValueSource = storage.BaseValueSourceInternal; object oldValue; Expression currentExpr = null; // Compute new value object effectiveValue; BaseValueSourceInternal effectiveValueKind; if (isCoerceOperation) { // Source and base value are unchanged during coercion operation effectiveValue = newValue; effectiveValueKind = oldBaseValueSource; // Get old value before it gets overriden oldValue = GetEffectiveValue(storage); } else { ComputeEffectiveValue(storage, out effectiveValue, out effectiveValueKind); // Check for early exit if effective value is not impacted (if we are doing // a coerce operation, we have to go through the update process) if (effectiveValueKind == oldBaseValueSource && newValueSource < effectiveValueKind) { // value source remains the same. // Exit if the newly set value is of lower precedence than the effective value. return(false); } // Get old value before it gets overriden oldValue = GetEffectiveValue(storage); currentExpr = (storage.IsExpression || storage.IsExpressionFromStyle) ? storage.ModifiedValue.BaseValue as Expression : null; #if USEASSERT // If the current base value is an Expression, it should have been detached by now // Or is the same instance as 'effectiveValue' (this occurs when we update a property bound to a // BindingExpression) global::System.Diagnostics.Debug.Assert(currentExpr == null || !currentExpr.IsAttached || object.ReferenceEquals(currentExpr, effectiveValue), "Binding expression should be detached."); #endif storage.ResetValue(); // Update the base value source storage.BaseValueSourceInternal = effectiveValueKind; } object computedValue; if (!isCoerceOperation) { var newExpr = effectiveValue as Expression; if (newExpr == null) { computedValue = storage.Property.PropertyType == typeof(string) ? effectiveValue?.ToString() : effectiveValue; storage.Value = computedValue; } else { #if USEASSERT global::System.Diagnostics.Debug.Assert(effectiveValueKind == BaseValueSourceInternal.Local || effectiveValueKind == BaseValueSourceInternal.LocalStyle); #endif // If the new Expression is the same as the current one, // the Expression is already attached bool isNewBinding = !object.ReferenceEquals(currentExpr, newExpr); if (isNewBinding) { if (newExpr.IsAttached) { throw new InvalidOperationException(string.Format("Cannot attach an instance of '{0}' multiple times", newExpr.GetType())); } newExpr.OnAttach(storage.Owner, storage.Property); storage.Value = newExpr; // Set the new base value } if (effectiveValueKind == BaseValueSourceInternal.Local) { storage.SetExpressionValue(storage.TypeMetadata.DefaultValue, newExpr); } else { storage.SetExpressionFromStyleValue(storage.TypeMetadata.DefaultValue, newExpr); } // 1- 'isNewBinding == true' means that we are attaching a new Expression. // 2- 'newValue is Expression == true' means that we are re-evaluating an Expression // (usually by calling RefreshExpressionCommon) // 3- Otherwise we are trying to change the value of a TwoWay binding. // In that case we have to preserve the Expression (this is not the case if the first two // situations), hence the following line : computedValue = isNewBinding || newValue is Expression?newExpr.GetValue(storage.Owner, storage.Property) : newValue; computedValue = storage.Property.PropertyType == typeof(string) ? computedValue?.ToString() : computedValue; storage.ModifiedValue.ExpressionValue = computedValue; } } else { computedValue = coerceWithCurrentValue ? newValue : GetCoercionBaseValue(storage); if (coerceValue) { storage.ResetCoercedValue(); } } // Coerce to current value if (coerceWithCurrentValue) { object baseValue = GetCoercionBaseValue(storage); ProcessCoerceValue(storage, ref computedValue, oldValue, baseValue, true); } // Coerce Value // We don't want to coerce the value if it's being reset to the property's default value if (storage.TypeMetadata.CoerceValueCallback != null && !(clearValue && storage.FullValueSource == (FullValueSource)BaseValueSourceInternal.Default)) { object baseValue = GetCoercionBaseValue(storage); ProcessCoerceValue(storage, ref computedValue, oldValue, baseValue, false); } // Reset old value inheritance context if (oldBaseValueSource == BaseValueSourceInternal.Local) { // Notes: // - Inheritance context is only handled by local value // - We use null instead of the actual DependencyProperty // as the parameter is ignored in the current implentation. storage.Owner.RemoveSelfAsInheritanceContext(oldValue, null /*storage.Property*/); } // Set new value inheritance context if (effectiveValueKind == BaseValueSourceInternal.Local) { // Check above storage.Owner.ProvideSelfAsInheritanceContext(computedValue, null /*storage.Property*/); } bool valueChanged; if (valueChanged = (storage.INTERNAL_IsVisualValueDirty || !ArePropertiesEqual(oldValue, computedValue, storage.Property.PropertyType))) { // Raise the PropertyChanged event if (!storage.TypeMetadata.Inherits || ShouldRaisePropertyChanged(storage)) { OnPropertyChanged(storage, oldValue, computedValue); } // Propagate to children if property is inherited if (storage.TypeMetadata.Inherits && propagateChanges) { if (storage.Owner is FrameworkElement rootElement) { InheritablePropertyChangeInfo info = new InheritablePropertyChangeInfo(rootElement, storage.Property, oldValue, oldBaseValueSource, computedValue, newValueSource); TreeWalkHelper.InvalidateOnInheritablePropertyChange(rootElement, info); } } storage.INTERNAL_IsVisualValueDirty = false; } // Update the source of the Binding, in case the previous value // of a property was a Binding and the Mode was "TwoWay": // Note: we know that oldBindingExpression.IsUpdating is false // because oldBindingExpression is only set in that case (otherwise, // it is null). if (currentExpr != null) { currentExpr.SetValue(storage.Owner, storage.Property, computedValue); } // Raise the InvalidateMeasure or InvalidateArrange storage.Owner.OnPropertyChanged(new DependencyPropertyChangedEventArgs(oldValue, newValue, storage.Property)); return(valueChanged); }