Beispiel #1
0
        [FriendAccessAllowed] // Built into Base, also used by Framework.
        internal object GetDefaultValue(DependencyObject owner, DependencyProperty property) 
        {
            Debug.Assert(owner != null && property != null,
                "Caller must provide owner and property or this method will throw in the event of a cache miss.");
 
            // If we are not using a DefaultValueFactory (common case)
            // just return _defaultValue 
            DefaultValueFactory defaultFactory = _defaultValue as DefaultValueFactory; 
            if (defaultFactory == null)
            { 
                return _defaultValue;
            }

            // If the owner is Sealed it must not have a cached Freezable default value, 
            // regardless of whether or not the owner is a Freezable.  The reason
            // for this is that a default created using the FreezableDefaultValueFactory 
            // will attempt to set itself as a local value if it is changed.  Since the owner 
            // is Sealed this will throw an exception.
            // 
            // The solution to this if the owner is a Freezable is to toss out all cached
            // default values when we Seal.  If the owner is not a Freezable we'll promote
            // the value to locally cached.  Either way no Sealed DO can have a cached
            // default value, so we'll return the frozen default value instead. 
            if (owner.IsSealed)
            { 
                return defaultFactory.DefaultValue; 
            }
 
            // See if we already have a valid default value that was
            // created by a prior call to GetDefaultValue.
            object result = GetCachedDefaultValue(owner, property);
 
            if (result != DependencyProperty.UnsetValue)
            { 
                // When sealing a DO we toss out all the cached values (see DependencyObject.Seal()). 
                // We technically only need to throw out cached values created via the
                // FreezableDefaultValueFactory, but it's more consistent this way. 
                Debug.Assert(!owner.IsSealed,
                    "If the owner is Sealed we should not have a cached default value");

                return result; 
            }
 
            // Otherwise we need to invoke the factory to create the DefaultValue 
            // for this property.
            result = defaultFactory.CreateDefaultValue(owner, property); 

            // Default value validation ensures that default values do not have
            // thread affinity. This is because a default value is typically
            // stored in the shared property metadata and handed out to all 
            // instances of the owning DependencyObject type.
            // 
            // DefaultValueFactory.CreateDefaultValue ensures that the default 
            // value has thread-affinity to the current thread.  We can thus
            // skip that portion of the default value validation by calling 
            // ValidateFactoryDefaultValue.

            Debug.Assert(!(result is DispatcherObject) || ((DispatcherObject)result).Dispatcher == owner.Dispatcher);
 
            property.ValidateFactoryDefaultValue(result);
 
            // Cache the created DefaultValue so that we can consistently hand 
            // out the same default each time we are asked.
            SetCachedDefaultValue(owner, property, result); 

            return result;
        }
        [FriendAccessAllowed] // Built into Base, also used by Framework.
        internal object GetDefaultValue(DependencyObject owner, DependencyProperty property)
        {
            Debug.Assert(owner != null && property != null,
                         "Caller must provide owner and property or this method will throw in the event of a cache miss.");

            // If we are not using a DefaultValueFactory (common case)
            // just return _defaultValue
            DefaultValueFactory defaultFactory = _defaultValue as DefaultValueFactory;

            if (defaultFactory == null)
            {
                return(_defaultValue);
            }

            // If the owner is Sealed it must not have a cached Freezable default value,
            // regardless of whether or not the owner is a Freezable.  The reason
            // for this is that a default created using the FreezableDefaultValueFactory
            // will attempt to set itself as a local value if it is changed.  Since the owner
            // is Sealed this will throw an exception.
            //
            // The solution to this if the owner is a Freezable is to toss out all cached
            // default values when we Seal.  If the owner is not a Freezable we'll promote
            // the value to locally cached.  Either way no Sealed DO can have a cached
            // default value, so we'll return the frozen default value instead.
            if (owner.IsSealed)
            {
                return(defaultFactory.DefaultValue);
            }

            // See if we already have a valid default value that was
            // created by a prior call to GetDefaultValue.
            object result = GetCachedDefaultValue(owner, property);

            if (result != DependencyProperty.UnsetValue)
            {
                // When sealing a DO we toss out all the cached values (see DependencyObject.Seal()).
                // We technically only need to throw out cached values created via the
                // FreezableDefaultValueFactory, but it's more consistent this way.
                Debug.Assert(!owner.IsSealed,
                             "If the owner is Sealed we should not have a cached default value");

                return(result);
            }

            // Otherwise we need to invoke the factory to create the DefaultValue
            // for this property.
            result = defaultFactory.CreateDefaultValue(owner, property);

            // Default value validation ensures that default values do not have
            // thread affinity. This is because a default value is typically
            // stored in the shared property metadata and handed out to all
            // instances of the owning DependencyObject type.
            //
            // DefaultValueFactory.CreateDefaultValue ensures that the default
            // value has thread-affinity to the current thread.  We can thus
            // skip that portion of the default value validation by calling
            // ValidateFactoryDefaultValue.

            Debug.Assert(!(result is DispatcherObject) || ((DispatcherObject)result).Dispatcher == owner.Dispatcher);

            property.ValidateFactoryDefaultValue(result);

            // Cache the created DefaultValue so that we can consistently hand
            // out the same default each time we are asked.
            SetCachedDefaultValue(owner, property, result);

            return(result);
        }