Beispiel #1
0
        /// <summary>
        /// Gets the value at the highest precedence level under the specified one
        /// E.G. If a property has a value both on the Animation, Local and Default
        /// precedences, and the given precedence is Animation, then the Local value is returned.
        /// </summary>
        /// <param name="precedence">The value precedence under which to fetch a value</param>
        /// <returns>The value at the highest precedence level under the specified one</returns>
        internal (object value, DependencyPropertyValuePrecedences precedence) GetValueUnderPrecedence(DependencyPropertyValuePrecedences precedence)
        {
            // Start from current precedence and find next highest
            for (int i = (int)precedence + 1; i < (int)DependencyPropertyValuePrecedences.DefaultValue; i++)
            {
                object value = Unwrap(_stack[i]);

                if (value != DependencyProperty.UnsetValue)
                {
                    return(value, (DependencyPropertyValuePrecedences)i);
                }
            }

            return(_stack[(int)DependencyPropertyValuePrecedences.DefaultValue], DependencyPropertyValuePrecedences.DefaultValue);
        }
Beispiel #2
0
        internal void ClearInvalidProperties(DependencyObject dependencyObject, Style incomingStyle, DependencyPropertyValuePrecedences precedence)
        {
            var oldSetters = CreateSetterMap();
            var newSetters = incomingStyle?.CreateSetterMap();

            foreach (var kvp in oldSetters)
            {
                if (kvp.Key is DependencyProperty dp)
                {
                    if (newSetters == null || !newSetters.ContainsKey(dp))
                    {
                        DependencyObjectExtensions.ClearValue(dependencyObject, dp, precedence);
                    }
                }
            }
        }
 /// <summary>
 /// Creates a SetValue precedence scoped override. All calls to SetValue
 /// on the specified instance will be set to the specified precedence.
 /// </summary>
 /// <param name="instance">The instance to override</param>
 /// <param name="precedence">The precedence to set</param>
 /// <returns>A disposable to dispose to cancel the override.</returns>
 internal static IDisposable OverrideLocalPrecedence(this object instance, DependencyPropertyValuePrecedences precedence)
 {
     return(GetStore(instance).OverrideLocalPrecedence(precedence));
 }
Beispiel #4
0
 internal object GetValue(DependencyPropertyValuePrecedences precedence)
 => Unwrap(_stack[(int)precedence]);
 /// <summary>
 /// Gets the value for the specified dependency property on the specific instance at
 /// the specified precedence.  As opposed to GetValue, this will not fall back to the highest
 /// precedence if this precedence is currently unset and will return unset value.
 /// </summary>
 /// <param name="instance">The instance on which the property is attached</param>
 /// <param name="property">The dependency property to get</param>
 /// <param name="precedence">The value precedence at which to fetch a value</param>
 /// <returns></returns>
 internal static object GetPrecedenceSpecificValue(this DependencyObject instance, DependencyProperty property, DependencyPropertyValuePrecedences precedence)
 {
     return(GetStore(instance).GetValue(property, precedence, true));
 }
 /// <summary>
 /// Get the value for the specified dependency property on the specific instance at
 /// the highest precedence level under the specified one.
 /// E.G. If a property has a value both on the Animation, Local and Default
 /// precedences, and the given precedence is Animation, then the Local value is returned.
 /// </summary>
 /// <param name="instance">The instance on which the property is attached</param>
 /// <param name="property">The dependency property to get</param>
 /// <param name="precedence">The value precedence under which to fetch a value</param>
 /// <returns></returns>
 internal static (object value, DependencyPropertyValuePrecedences precedence) GetValueUnderPrecedence(this DependencyObject instance, DependencyProperty property, DependencyPropertyValuePrecedences precedence)
 {
     return(GetStore(instance).GetValueUnderPrecedence(property, precedence));
 }
Beispiel #7
0
 public ResourceBinding(SpecializedResourceDictionary.ResourceKey resourceKey, ResourceUpdateReason updateReason, object?parseContext, DependencyPropertyValuePrecedences precedence, BindingPath?setterBindingPath)
 {
     ResourceKey       = resourceKey;
     UpdateReason      = updateReason;
     ParseContext      = parseContext;
     Precedence        = precedence;
     SetterBindingPath = setterBindingPath;
 }
 /// <summary>
 /// Clears the value for the specified dependency property on the specified instance.
 /// </summary>
 /// <param name="instance">The instance on which the property is attached</param>
 /// <param name="property">The dependency property to get</param>
 /// <param name="precedence">The value precendence to assign</param>
 internal static void ClearValue(this DependencyObject instance, DependencyProperty property, DependencyPropertyValuePrecedences precedence)
 {
     SetValue(instance, property, DependencyProperty.UnsetValue, precedence);
 }
Beispiel #9
0
 public ResourceBinding(object resourceKey, bool isThemeResourceExtension, object parseContext, DependencyPropertyValuePrecedences precedence)
 {
     ResourceKey = new SpecializedResourceDictionary.ResourceKey(resourceKey);
     IsThemeResourceExtension = isThemeResourceExtension;
     ParseContext             = parseContext;
     Precedence = precedence;
 }
        internal static ValueUnsetterHandler GetValueUnsetter(Type type, string property, DependencyPropertyValuePrecedences precedence)
        {
            var key = CachedTuple.Create(type, property, precedence);

            ValueUnsetterHandler result;

            lock (_getValueUnsetter)
            {
                if (!_getValueUnsetter.TryGetValue(key, out result))
                {
                    _getValueUnsetter.Add(key, result = InternalGetValueUnsetter(type, property, precedence));
                }
            }

            return(result);
        }
Beispiel #11
0
 public ResourceBinding(object resourceKey, bool isThemeResourceExtension, object parseContext, DependencyPropertyValuePrecedences precedence)
 {
     ResourceKey = resourceKey;
     IsThemeResourceExtension = isThemeResourceExtension;
     ParseContext             = parseContext;
     Precedence = precedence;
 }
Beispiel #12
0
        private void OnDataContextChanged(object providedDataContext, object actualDataContext, DependencyPropertyValuePrecedences precedence)
        {
            var dataContextBinding = _properties.FindDataContextBinding();

            if (dataContextBinding != null && precedence == DependencyPropertyValuePrecedences.Inheritance)
            {
                // Set the DataContext for the bindings using the current DataContext, except for the
                // binding to the DataContext itself, which must use the inherited DataContext.
                //
                // This is to avoid recursion when the datacontext.
                //
                // The inherited DataContext may also be null in the case of non-inherited data binding
                // when using the custom target parameter in SetBinding.
                if (dataContextBinding.ParentBinding.RelativeSource == null)
                {
                    dataContextBinding.DataContext = providedDataContext;
                }
            }
            else
            {
#if !HAS_EXPENSIVE_TRYFINALLY
                // The try/finally incurs a very large performance hit in mono-wasm, and SetValue is in a very hot execution path.
                // See https://github.com/mono/mono/issues/13653 for more details.
                try
#endif
                {
                    if (_isApplyingDataContextBindings || _bindingsSuspended)
                    {
                        // If we reach this point, this means that a propagation loop has been detected, and
                        // we can skip the current binder.
                        // This can happen if a DependencyObject-typed DependencyProperty contains a reference
                        // to one of its ancestors.
                        return;
                    }

                    _isApplyingDataContextBindings = true;

                    using (TryWriteDataContextChangedEventActivity())
                    {
                        _properties.ApplyDataContext(actualDataContext);

                        ApplyChildrenBindable(actualDataContext, isTemplatedParent: false);
                    }
                }
#if !HAS_EXPENSIVE_TRYFINALLY
                finally
#endif
                {
                    _isApplyingDataContextBindings = false;
                }
            }
        }
Beispiel #13
0
 public Style()
 {
     Precedence = DependencyPropertyValuePrecedences.ExplicitStyle;
 }
Beispiel #14
0
 public ResourceBinding(SpecializedResourceDictionary.ResourceKey resourceKey, bool isThemeResourceExtension, object?parseContext, DependencyPropertyValuePrecedences precedence, BindingPath?setterBindingPath)
 {
     ResourceKey = resourceKey;
     IsThemeResourceExtension = isThemeResourceExtension;
     ParseContext             = parseContext;
     Precedence        = precedence;
     SetterBindingPath = setterBindingPath;
 }
Beispiel #15
0
        private void OnDataContextChanged(object providedDataContext, object actualDataContext, DependencyPropertyValuePrecedences precedence)
        {
            var dataContextBinding = _properties.FindDataContextBinding();

            if (dataContextBinding != null && precedence == DependencyPropertyValuePrecedences.Inheritance)
            {
                // Set the DataContext for the bindings using the current DataContext, except for the
                // binding to the DataContext itself, which must use the inherited DataContext.
                //
                // This is to avoid recursion when the datacontext.
                //
                // The inherited DataContext may also be null in the case of non-inherited data binding
                // when using the custom target parameter in SetBinding.
                if (dataContextBinding.ParentBinding.RelativeSource == null)
                {
                    dataContextBinding.DataContext = providedDataContext;
                }
            }
            else
            {
                try
                {
                    if (_isApplyingDataContextBindings || _bindingsSuspended)
                    {
                        // If we reach this point, this means that a propagation loop has been detected, and
                        // we can skip the current binder.
                        // This can happen if a DependencyObject-typed DependencyProperty contains a reference
                        // to one of its ancestors.
                        return;
                    }

                    _isApplyingDataContextBindings = true;

                    using (TryWriteDataContextChangedEventActivity())
                    {
                        _properties.ApplyDataContext(actualDataContext);

                        ApplyChildrenBindable(actualDataContext, isTemplatedParent: false);
                    }
                }
                finally
                {
                    _isApplyingDataContextBindings = false;
                }
            }
        }