private object TryProvideValueImpl(IServiceProvider serviceProvider, bool allowDeferredReference, bool mustReturnDeferredResourceReference)
        {
            // Get prefetchedValue
            DeferredResourceReference prefetchedValue = PrefetchedValue;

            object value;

            if (prefetchedValue == null)
            {
                // Do a normal look up.
                value = FindResourceInEnviroment(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);
            }
            else
            {
                // If we have a Deferred Value, first check the current parse stack for a better (nearer)
                // value.  This happens when this is a parse of deferred content and there is another
                // Resource Dictionary availible above this, yet still part of this deferred content.
                // This searches up to the outer most enclosing resource dictionary.
                value = FindResourceInDeferredContent(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);

                // If we didn't find a new value in this part of deferred content
                // then use the existing prefetchedValue (DeferredResourceReference)
                if (value == DependencyProperty.UnsetValue)
                {
                    value = allowDeferredReference
                             ? prefetchedValue
                             : prefetchedValue.GetValue(BaseValueSourceInternal.Unknown);
                }
            }
            return(value);
        }
        /// <summary>
        /// This method is called when the cached value of the resource has
        /// been invalidated.  E.g. after a new Resources property is set somewhere
        /// in the ancestory.
        /// </summary>
        private void InvalidateCacheValue()
        {
            object resource = _cachedResourceValue;

            // If the old value was a DeferredResourceReference, it should be
            // removed from its Dictionary's list to avoid a leak (bug 1624666).
            DeferredResourceReference deferredResourceReference = _cachedResourceValue as DeferredResourceReference;

            if (deferredResourceReference != null)
            {
                if (deferredResourceReference.IsInflated)
                {
                    // use the inflated value for the Freezable test below
                    resource = deferredResourceReference.Value;
                }
                else
                {
                    // stop listening for the Inflated event
                    if (ReadInternalState(InternalState.IsListeningForInflated))
                    {
                        deferredResourceReference.RemoveInflatedListener(this);
                        WriteInternalState(InternalState.IsListeningForInflated, false);
                    }
                }

                deferredResourceReference.RemoveFromDictionary();
            }

            StopListeningForFreezableChanges(resource);

            _cachedResourceValue = null;
            WriteInternalState(InternalState.HasCachedResourceValue, false);
        }
        // Token: 0x06000875 RID: 2165 RVA: 0x0001B8AC File Offset: 0x00019AAC
        internal object GetRawValue(DependencyObject d, out object source, DependencyProperty dp)
        {
            if (!this.ReadInternalState(ResourceReferenceExpression.InternalState.IsMentorCacheValid))
            {
                this._mentorCache = Helper.FindMentor(d);
                this.WriteInternalState(ResourceReferenceExpression.InternalState.IsMentorCacheValid, true);
                if (this._mentorCache != null && this._mentorCache != this._targetObject)
                {
                    FrameworkElement        frameworkElement;
                    FrameworkContentElement frameworkContentElement;
                    Helper.DowncastToFEorFCE(this._mentorCache, out frameworkElement, out frameworkContentElement, true);
                    if (frameworkElement != null)
                    {
                        frameworkElement.ResourcesChanged += this.InvalidateExpressionValue;
                    }
                    else
                    {
                        frameworkContentElement.ResourcesChanged += this.InvalidateExpressionValue;
                    }
                }
            }
            object obj;

            if (this._mentorCache != null)
            {
                FrameworkElement        fe;
                FrameworkContentElement fce;
                Helper.DowncastToFEorFCE(this._mentorCache, out fe, out fce, true);
                obj = FrameworkElement.FindResourceInternal(fe, fce, dp, this._resourceKey, null, true, false, null, false, out source);
            }
            else
            {
                obj = FrameworkElement.FindResourceFromAppOrSystem(this._resourceKey, out source, false, true, false);
            }
            if (obj == null)
            {
                obj = DependencyProperty.UnsetValue;
            }
            this._cachedResourceValue = obj;
            this.WriteInternalState(ResourceReferenceExpression.InternalState.HasCachedResourceValue, true);
            object resource = obj;
            DeferredResourceReference deferredResourceReference = obj as DeferredResourceReference;

            if (deferredResourceReference != null)
            {
                if (deferredResourceReference.IsInflated)
                {
                    resource = (deferredResourceReference.Value as Freezable);
                }
                else if (!this.ReadInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated))
                {
                    deferredResourceReference.AddInflatedListener(this);
                    this.WriteInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated, true);
                }
            }
            this.ListenForFreezableChanges(resource);
            return(obj);
        }
 // Token: 0x06000881 RID: 2177 RVA: 0x0001BC70 File Offset: 0x00019E70
 internal void OnDeferredResourceInflated(DeferredResourceReference deferredResourceReference)
 {
     if (this.ReadInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated))
     {
         deferredResourceReference.RemoveInflatedListener(this);
         this.WriteInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated, false);
     }
     this.ListenForFreezableChanges(deferredResourceReference.Value);
 }
        private object TryProvideValueWithDiagnosticEvent(IServiceProvider serviceProvider, bool allowDeferredReference, bool mustReturnDeferredResourceReference)
        {
            IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

            if (provideValueTarget == null || provideValueTarget.TargetObject == null || provideValueTarget.TargetProperty == null ||
                ResourceDictionaryDiagnostics.ShouldIgnoreProperty(provideValueTarget.TargetProperty))
            {
                // if there's no target, or target is ignorable, get the value the quick way.
                return(TryProvideValueImpl(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference));
            }

            ResourceDictionaryDiagnostics.LookupResult result;
            object value;
            bool   success = false;

            try
            {
                // request a result of the lookup
                result = ResourceDictionaryDiagnostics.RequestLookupResult(this);

                // do the lookup - the ResourceDictionary that resolves the reference will fill in the result
                value = TryProvideValueImpl(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);

                // for the purposes of diagnostics, a deferred reference is a success -
                // we only need the dictionary that holds the value, not the value itself
                DeferredResourceReference deferredReference = value as DeferredResourceReference;
                if (deferredReference != null)
                {
                    success = true;
                    ResourceDictionary dict = deferredReference.Dictionary;
                    if (dict != null)
                    {
                        // the result may not have been recorded yet
                        ResourceDictionaryDiagnostics.RecordLookupResult(ResourceKey, dict);
                    }
                }
                else
                {
                    success = (value != DependencyProperty.UnsetValue);
                }
            }
            finally
            {
                // revert the request
                ResourceDictionaryDiagnostics.RevertRequest(this, success);
            }

            // raise the diagnostic event
            if (success)
            {
                ResourceDictionaryDiagnostics.OnStaticResourceResolved(provideValueTarget.TargetObject, provideValueTarget.TargetProperty, result);
            }

            return(value);
        }
        // when a deferred resource reference is inflated, the value may need extra
        // work
        internal void OnDeferredResourceInflated(DeferredResourceReference deferredResourceReference)
        {
            if (ReadInternalState(InternalState.IsListeningForInflated))
            {
                // once the value is inflated, stop listening for the event
                deferredResourceReference.RemoveInflatedListener(this);
                WriteInternalState(InternalState.IsListeningForInflated, false);
            }

            ListenForFreezableChanges(deferredResourceReference.Value);
        }
        // Token: 0x06000864 RID: 2148 RVA: 0x0001B4A4 File Offset: 0x000196A4
        private object TryProvideValueImpl(IServiceProvider serviceProvider, bool allowDeferredReference, bool mustReturnDeferredResourceReference)
        {
            DeferredResourceReference prefetchedValue = this.PrefetchedValue;
            object obj;

            if (prefetchedValue == null)
            {
                obj = this.FindResourceInEnviroment(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);
            }
            else
            {
                obj = this.FindResourceInDeferredContent(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);
                if (obj == DependencyProperty.UnsetValue)
                {
                    obj = (allowDeferredReference ? prefetchedValue : prefetchedValue.GetValue(BaseValueSourceInternal.Unknown));
                }
            }
            return(obj);
        }
        // Token: 0x06000863 RID: 2147 RVA: 0x0001B3DC File Offset: 0x000195DC
        private object TryProvideValueWithDiagnosticEvent(IServiceProvider serviceProvider, bool allowDeferredReference, bool mustReturnDeferredResourceReference)
        {
            IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

            if (provideValueTarget == null || provideValueTarget.TargetObject == null || provideValueTarget.TargetProperty == null || ResourceDictionaryDiagnostics.ShouldIgnoreProperty(provideValueTarget.TargetProperty))
            {
                return(this.TryProvideValueImpl(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference));
            }
            bool flag = false;

            ResourceDictionaryDiagnostics.LookupResult result;
            object obj;

            try
            {
                result = ResourceDictionaryDiagnostics.RequestLookupResult(this);
                obj    = this.TryProvideValueImpl(serviceProvider, allowDeferredReference, mustReturnDeferredResourceReference);
                DeferredResourceReference deferredResourceReference = obj as DeferredResourceReference;
                if (deferredResourceReference != null)
                {
                    flag = true;
                    ResourceDictionary dictionary = deferredResourceReference.Dictionary;
                    if (dictionary != null)
                    {
                        ResourceDictionaryDiagnostics.RecordLookupResult(this.ResourceKey, dictionary);
                    }
                }
                else
                {
                    flag = (obj != DependencyProperty.UnsetValue);
                }
            }
            finally
            {
                ResourceDictionaryDiagnostics.RevertRequest(this, flag);
            }
            if (flag)
            {
                ResourceDictionaryDiagnostics.OnStaticResourceResolved(provideValueTarget.TargetObject, provideValueTarget.TargetProperty, result);
            }
            return(obj);
        }
        // Token: 0x0600087A RID: 2170 RVA: 0x0001BA78 File Offset: 0x00019C78
        private void InvalidateCacheValue()
        {
            object resource = this._cachedResourceValue;
            DeferredResourceReference deferredResourceReference = this._cachedResourceValue as DeferredResourceReference;

            if (deferredResourceReference != null)
            {
                if (deferredResourceReference.IsInflated)
                {
                    resource = deferredResourceReference.Value;
                }
                else if (this.ReadInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated))
                {
                    deferredResourceReference.RemoveInflatedListener(this);
                    this.WriteInternalState(ResourceReferenceExpression.InternalState.IsListeningForInflated, false);
                }
                deferredResourceReference.RemoveFromDictionary();
            }
            this.StopListeningForFreezableChanges(resource);
            this._cachedResourceValue = null;
            this.WriteInternalState(ResourceReferenceExpression.InternalState.HasCachedResourceValue, false);
        }
Esempio n. 10
0
        // when a deferred resource reference is inflated, the value may need extra
        // work
        internal void OnDeferredResourceInflated(DeferredResourceReference deferredResourceReference)
        {
            if (ReadInternalState(InternalState.IsListeningForInflated))
            {
                // once the value is inflated, stop listening for the event
                deferredResourceReference.RemoveInflatedListener(this);
                WriteInternalState(InternalState.IsListeningForInflated, false);
            }

            ListenForFreezableChanges(deferredResourceReference.Value);
        }
        /// <summary>
        ///     Called to evaluate the ResourceReferenceExpression value
        /// </summary>
        /// <param name="d">DependencyObject being queried</param>
        /// <param name="source">Source object that the resource is found on</param>
        /// <param name="dp">DependencyProperty</param>
        /// <returns>Computed value. Unset if unavailable.</returns>
        /// <remarks>
        /// This routine has been separated from the above GetValue call because it is
        /// invoked by the ResourceReferenceExpressionConverter during serialization.
        /// </remarks>
        internal object GetRawValue(DependencyObject d, out object source, DependencyProperty dp)
        {
            // Find the mentor node to invoke FindResource on. For example
            // <Button>
            //   <Button.Background>
            //     <SolidColorBrush Color="{DynamicResource MyColor}" />
            //   </Button.Background>
            // </Button
            // Button is the mentor for the ResourceReference on SolidColorBrush
            if (ReadInternalState(InternalState.IsMentorCacheValid) == false)
            {
                // Find the mentor by walking up the InheritanceContext
                // links and update the cache
                _mentorCache = Helper.FindMentor(d);
                WriteInternalState(InternalState.IsMentorCacheValid, true);

                // If the mentor is different from the targetObject as will be the case
                // in the example described above, make sure you listen for ResourcesChanged
                // event on the mentor. That way you will be notified of ResourceDictionary
                // changes as well as logical tree changes
                if (_mentorCache != null && _mentorCache != _targetObject)
                {
                    Debug.Assert(_targetObject == d, "TargetObject that this expression is attached to must be the same as the one on which its value is being queried");

                    FrameworkElement        mentorFE;
                    FrameworkContentElement mentorFCE;
                    Helper.DowncastToFEorFCE(_mentorCache, out mentorFE, out mentorFCE, true);

                    if (mentorFE != null)
                    {
                        mentorFE.ResourcesChanged += new EventHandler(InvalidateExpressionValue);
                    }
                    else
                    {
                        mentorFCE.ResourcesChanged += new EventHandler(InvalidateExpressionValue);
                    }
                }
            }

            object resource;

            if (_mentorCache != null)
            {
                FrameworkElement        fe;
                FrameworkContentElement fce;
                Helper.DowncastToFEorFCE(_mentorCache, out fe, out fce, true /*throwIfNeither*/);

                // If there is a mentor do a FindResource call starting at that node
                resource = FrameworkElement.FindResourceInternal(fe,
                                                                 fce,
                                                                 dp,
                                                                 _resourceKey,
                                                                 null,  // unlinkedParent
                                                                 true,  // allowDeferredResourceReference
                                                                 false, // mustReturnDeferredResourceReference
                                                                 null,  // boundaryElement
                                                                 false, // disableThrowOnResourceFailure
                                                                 out source);
            }
            else
            {
                // If there is no mentor then simply search the App and the Themes for the right resource
                resource = FrameworkElement.FindResourceFromAppOrSystem(_resourceKey,
                                                                        out source,
                                                                        false, // disableThrowOnResourceFailure
                                                                        true,  // allowDeferredResourceReference
                                                                        false /* mustReturnDeferredResourceReference*/);
            }

            if (resource == null)
            {
                // Assuming that null means the value doesn't exist in the resources section
                resource = DependencyProperty.UnsetValue;
            }

            // Update the cached values with this resource instance
            _cachedResourceValue = resource;
            WriteInternalState(InternalState.HasCachedResourceValue, true);

            object effectiveResource = resource;
            DeferredResourceReference deferredResourceReference = resource as DeferredResourceReference;

            if (deferredResourceReference != null)
            {
                if (deferredResourceReference.IsInflated)
                {
                    // use the inflated value in the Freezable test below
                    effectiveResource = deferredResourceReference.Value as Freezable;
                }
                else
                {
                    // listen for inflation, so we can do the Freezable test then
                    if (!ReadInternalState(InternalState.IsListeningForInflated))
                    {
                        deferredResourceReference.AddInflatedListener(this);
                        WriteInternalState(InternalState.IsListeningForInflated, true);
                    }
                }
            }

            ListenForFreezableChanges(effectiveResource);

            // Return the resource
            return(resource);
        }
Esempio n. 12
0
        /// <summary>
        /// Fetches the resource corresponding to the given key from this dictionary. 
        /// Returns a DeferredResourceReference if the object has not been inflated yet.
        /// </summary>
        internal object FetchResource(
            object      resourceKey, 
            bool        allowDeferredResourceReference,
            bool        mustReturnDeferredResourceReference, 
            out bool    canCache) 
        {
            Debug.Assert(resourceKey != null, "ResourceKey cannot be null"); 

            if (allowDeferredResourceReference)
            {
                if (ContainsBamlObjectFactory(resourceKey) || 
                    (mustReturnDeferredResourceReference && Contains(resourceKey)))
                { 
                    canCache = false; 

                    DeferredResourceReference deferredResourceReference; 
                    if (!IsThemeDictionary)
                    {
                        if (_ownerApps != null)
                        { 
                            deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
                        } 
                        else 
                        {
                            deferredResourceReference = new DeferredResourceReference(this, resourceKey); 
                        }

                        // Cache the deferredResourceReference so that it can be validated
                        // in case of a dictionary change prior to its inflation 
                        if (_deferredResourceReferences == null)
                        { 
                            _deferredResourceReferences = new WeakReferenceList(); 
                        }
 
                        _deferredResourceReferences.Add( deferredResourceReference, true /*SkipFind*/);
                    }
                    else
                    { 
                        deferredResourceReference = new DeferredThemeResourceReference(this, resourceKey);
                    } 
 
                    return deferredResourceReference;
                } 
            }

            return GetValue(resourceKey, out canCache);
        } 
Esempio n. 13
0
 internal StaticResourceHolder(object resourceKey, DeferredResourceReference prefetchedValue) : base(resourceKey) 
 { 
     _prefetchedValue = prefetchedValue;
 }