| File: System\Windows\DependencyPropertyHelper.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // // Description: Helper class for miscellaneous framework-level features related // to DependencyProperties. // // See spec at GetValueSource.mht // using MS.Internal; namespace System.Windows { /// <summary> /// Source of a DependencyProperty value. /// </summary> public enum BaseValueSource { /// <summary> The source is not known by the Framework. </summary> Unknown = BaseValueSourceInternal.Unknown, /// <summary> Default value, as defined by property metadata. </summary> Default = BaseValueSourceInternal.Default, /// <summary> Inherited from an ancestor. </summary> Inherited = BaseValueSourceInternal.Inherited, /// <summary> Default Style for the current theme. </summary> DefaultStyle = BaseValueSourceInternal.ThemeStyle, /// <summary> Trigger in the default Style for the current theme. </summary> DefaultStyleTrigger = BaseValueSourceInternal.ThemeStyleTrigger, /// <summary> Style setter. </summary> Style = BaseValueSourceInternal.Style, /// <summary> Trigger in the Template. </summary> TemplateTrigger = BaseValueSourceInternal.TemplateTrigger, /// <summary> Trigger in the Style. </summary> StyleTrigger = BaseValueSourceInternal.StyleTrigger, /// <summary> Implicit Style reference. </summary> ImplicitStyleReference = BaseValueSourceInternal.ImplicitReference, /// <summary> Template that created the element. </summary> ParentTemplate = BaseValueSourceInternal.ParentTemplate, /// <summary> Trigger in the Template that created the element. </summary> ParentTemplateTrigger = BaseValueSourceInternal.ParentTemplateTrigger, /// <summary> Local value. </summary> Local = BaseValueSourceInternal.Local, } /// <summary> /// This struct contains the information returned from /// DependencyPropertyHelper.GetValueSource. /// </summary> public struct ValueSource { internal ValueSource(BaseValueSourceInternal source, bool isExpression, bool isAnimated, bool isCoerced, bool isCurrent) { // this cast is justified because the public BaseValueSource enum // values agree with the internal BaseValueSourceInternal enum values. _baseValueSource = (BaseValueSource)source; _isExpression = isExpression; _isAnimated = isAnimated; _isCoerced = isCoerced; _isCurrent = isCurrent; } /// <summary> /// The base value source. /// </summary> public BaseValueSource BaseValueSource { get { return _baseValueSource; } } /// <summary> /// True if the value came from an Expression. /// </summary> public bool IsExpression { get { return _isExpression; } } /// <summary> /// True if the value came from an animation. /// </summary> public bool IsAnimated { get { return _isAnimated; } } /// <summary> /// True if the value was coerced. /// </summary> public bool IsCoerced { get { return _isCoerced; } } /// <summary> /// True if the value was set by SetCurrentValue. /// </summary> public bool IsCurrent { get { return _isCurrent; } } #region Object overrides - required by FxCop /// <summary> /// Return the hash code for this ValueSource. /// </summary> public override int GetHashCode() { return _baseValueSource.GetHashCode(); } /// <summary> /// True if this ValueSource equals the argument. /// </summary> public override bool Equals(object o) { if (o is ValueSource that) { return this._baseValueSource == that._baseValueSource && this._isExpression == that._isExpression && this._isAnimated == that._isAnimated && this._isCoerced == that._isCoerced; } else { return false; } } /// <summary> /// True if the two arguments are equal. /// </summary> public static bool operator==(ValueSource vs1, ValueSource vs2) { return vs1.Equals(vs2); } /// <summary> /// True if the two arguments are unequal. /// </summary> public static bool operator!=(ValueSource vs1, ValueSource vs2) { return !vs1.Equals(vs2); } #endregion Object overrides - required by FxCop private BaseValueSource _baseValueSource; private bool _isExpression; private bool _isAnimated; private bool _isCoerced; private bool _isCurrent; } /// <summary> /// Helper class for miscellaneous framework-level features related /// to DependencyProperties. /// </summary> public static class DependencyPropertyHelper { /// <summary> /// Return the source of the value for the given property. /// </summary> public static ValueSource GetValueSource(DependencyObject dependencyObject, DependencyProperty dependencyProperty) { ArgumentNullException.ThrowIfNull(dependencyObject); ArgumentNullException.ThrowIfNull(dependencyProperty); dependencyObject.VerifyAccess(); bool hasModifiers, isExpression, isAnimated, isCoerced, isCurrent; BaseValueSourceInternal source = dependencyObject.GetValueSource(dependencyProperty, null, out hasModifiers, out isExpression, out isAnimated, out isCoerced, out isCurrent); return new ValueSource(source, isExpression, isAnimated, isCoerced, isCurrent); } /// <summary> /// Returns true if the given element belongs to an instance of a template /// that defines a value for the given property that may change during runtime /// based on changes elsewhere. /// For example, values set by Binding, TemplateBinding, or DynamicResource. /// </summary> /// <param name="elementInTemplate">element belonging to a template instance</param> /// <param name="dependencyProperty">property</param> /// <remarks> /// This method provides more detailed information in cases where /// the BaseValueSource is ParentTemplate. The information is primarily /// of use to diagnostic tools. /// </remarks> public static bool IsTemplatedValueDynamic(DependencyObject elementInTemplate, DependencyProperty dependencyProperty) { ArgumentNullException.ThrowIfNull(elementInTemplate); ArgumentNullException.ThrowIfNull(dependencyProperty); FrameworkObject child = new FrameworkObject(elementInTemplate); DependencyObject templatedParent = child.TemplatedParent; if (templatedParent == null) { throw new ArgumentException(SR.ElementMustBelongToTemplate, nameof(elementInTemplate)); } int templateChildIndex = child.TemplateChildIndex; return StyleHelper.IsValueDynamic(templatedParent, templateChildIndex, dependencyProperty); } } }