Пример #1
0
        /// <summary>Handles cases where a markup extension provides a value for a property of <see cref="T:System.Windows.Setter" /> object.</summary>
        /// <param name="targetObject">The object where the markup extension sets the value.</param>
        /// <param name="eventArgs">Data that is relevant for markup extension processing.</param>
        // Token: 0x0600089C RID: 2204 RVA: 0x0001BFD0 File Offset: 0x0001A1D0
        public static void ReceiveMarkupExtension(object targetObject, XamlSetMarkupExtensionEventArgs eventArgs)
        {
            if (targetObject == null)
            {
                throw new ArgumentNullException("targetObject");
            }
            if (eventArgs == null)
            {
                throw new ArgumentNullException("eventArgs");
            }
            Setter setter = targetObject as Setter;

            if (setter == null || eventArgs.Member.Name != "Value")
            {
                return;
            }
            MarkupExtension markupExtension = eventArgs.MarkupExtension;

            if (markupExtension is StaticResourceExtension)
            {
                StaticResourceExtension staticResourceExtension = markupExtension as StaticResourceExtension;
                setter.Value      = staticResourceExtension.ProvideValueInternal(eventArgs.ServiceProvider, true);
                eventArgs.Handled = true;
                return;
            }
            if (markupExtension is DynamicResourceExtension || markupExtension is BindingBase)
            {
                setter.Value      = markupExtension;
                eventArgs.Handled = true;
            }
        }
Пример #2
0
 private static Style GetStyle(IServiceProvider service,
                               StaticResourceExtension resource)
 {
     var style = resource.ProvideValue(service) as Style;
     if (style == null)
     {
         throw new InvalidOperationException(
             string.Format(
                 "Could not find style with resource key {0}.",
                 resource.ResourceKey));
     }
     
     return style;
 }
Пример #3
0
 /// <summary>
 /// Returns a style that merges all styles with the keys specified in the constructor.
 /// </summary>
 /// <param name="serviceProvider">The service provider for this markup extension.</param>
 /// <returns>A style that merges all styles with the keys specified in the constructor.</returns>
 public override object ProvideValue(IServiceProvider serviceProvider)
 {
     Style resultStyle = new Style();
     foreach(string currentResourceKey in resourceKeys) {
         object key = currentResourceKey;
         if(currentResourceKey == ".") {
             IProvideValueTarget service = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
             key = service.TargetObject.GetType();
         }
         Style currentStyle = new StaticResourceExtension(key).ProvideValue(serviceProvider) as Style;
         if(currentStyle == null)
             throw new InvalidOperationException("Could not find style with resource key " + currentResourceKey + ".");
         resultStyle.Merge(currentStyle);
     }
     return resultStyle;
 }
Пример #4
0
        /// <summary>
        /// Returns a style that merges all styles with the keys specified by ResourceKeys property.
        /// </summary>
        public override object ProvideValue( IServiceProvider serviceProvider )
        {
            Contract.RequiresNotNull( ResourceKeys, "ResourceKeys" );

            var resourceKeys = ResourceKeys.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries );

            Contract.Requires( resourceKeys.Length > 0, "No input resource keys specified." );

            var resultStyle = new Style();

            foreach( var currentResourceKey in resourceKeys )
            {
                var currentStyle = new StaticResourceExtension( currentResourceKey ).ProvideValue( serviceProvider ) as Style;

                Contract.Invariant( currentStyle != null, "Could not find style with resource key " + currentResourceKey + "." );

                AddTo( currentStyle, resultStyle );
            }

            return resultStyle;
        }
Пример #5
0
        /// <summary> 
        /// Convert the OptimizedStaticResource and StaticResource items into StaticResourceHolders.
        /// A StaticResourceHolder is derived from StaticResourceExtension and is a MarkupExtension.
        /// The differences is that it contain a DeferredResourceReference as its "PrefetchedValue".
        /// DeferredResourceReferences hold the dictionary and the key of the resource.  It is a 
        /// way of looking up the reference now (for later use) but not expanding the entry.
        /// Also the dictionary has a reference back to the Deferrred Reference.  If dictionary entry 
        /// is modifed the DeferredResourceReference is told and it will grab the old value. 
        /// StaticResourceHolder is a MarkupExtension and thus can be returned as a "Value" in the Node Stream.
        /// 
        /// Issue:  If there is a ResourceDictionary inside the deferred entry, the entries inside that
        /// RD will not be evaluated when resolving DeferredResourceReferences for a key in that same entry.
        /// Thus the OptimizedStaticResource will either be erronously "not found" or may even map to some
        /// incorrect value higher in the parse tree.  So... In StaticResourceExtension.ProvideValue() 
        /// when we have a DeferredResourceReference we search the Deferred Content for a better
        /// closer value before using the DeferredReference. 
        /// See StaticResourceExtension.FindTheResourceDictionary() for more details. 
        /// </summary>
 
        // As a memory optimization this method is passed a staticResourceExtension instance to use as
        // a worker when calling TryProvideValueInternal, which saves us having to allocate on every call.
        private void SetOptimizedStaticResources(IList<object> staticResources, IServiceProvider serviceProvider, StaticResourceExtension staticResourceWorker)
        { 
            Debug.Assert(staticResources != null && staticResources.Count > 0);
            for (int i = 0; i < staticResources.Count; i++) 
            { 
                object keyValue = null;
 
                // Process OptimizedStaticResource
                var optimizedStaticResource = staticResources[i] as OptimizedStaticResource;
                if (optimizedStaticResource != null)
                { 
                    keyValue = optimizedStaticResource.KeyValue;
                } 
                else 
                {
                    // Process StaticResource  (it holds the NodeList of the StaticResourceExtension) 
                    var staticResource = staticResources[i] as StaticResource;
                    if (staticResource != null)
                    {
                        // find and evaluate the Key value of the SR in the SR's node stream. 
                        keyValue = GetStaticResourceKeyValue(staticResource, serviceProvider);
                        Debug.Assert(keyValue != null, "Didn't find the ResourceKey property or x:PositionalParameters directive"); 
                    } 
                    else
                    { 
                        Debug.Assert(false, "StaticResources[] entry is not a StaticResource not OptimizedStaticResource");
                        continue;  // other types of entries are not processed.
                    }
                } 

                // Lookup the Key in the current context.  [And return a Deferred Reference Holding SR to it] 
                // The current context is the Key table at the top of the Compiled Dictionary. 
                // We will look at keys above us in this dictionary and in the dictionaries in objects above
                // us on the parse stack.  And then look in the App and System Themems. 
                // This isn't always good enough.  The Static Resource referenced inside the entry may refer
                // to a entry in a sub-dictionary inside the deferred entry.   There is other code, later
                // when evaluating StaticResourceHolders, that does an search of the part that is missed here.
                staticResourceWorker.ResourceKey = keyValue; 
                object obj = staticResourceWorker.TryProvideValueInternal(serviceProvider, true /*allowDeferredReference*/, true /* mustReturnDeferredResourceReference */);
 
                Debug.Assert(obj is DeferredResourceReference); 
                staticResources[i] = new StaticResourceHolder(keyValue, obj as DeferredResourceReference);
            } 
        }
Пример #6
0
        private void SetKeys(IList<KeyRecord> keyCollection, IServiceProvider serviceProvider) 
        {
            _numDefer = keyCollection.Count;

            // Allocate one StaticResourceExtension object to use as a "worker". 
            StaticResourceExtension staticResourceWorker = new StaticResourceExtension();
 
            // Use the array Count property to avoid range checking inside the loop 
            for (int i = 0; i < keyCollection.Count; i++)
            { 
                KeyRecord keyRecord = keyCollection[i];
                if (keyRecord != null)
                {
                    object value = GetKeyValue(keyRecord, serviceProvider); 

                    // Update the HasImplicitStyles flag 
                    UpdateHasImplicitStyles(value); 

                    if (keyRecord != null && keyRecord.HasStaticResources) 
                    {
                        SetOptimizedStaticResources(keyRecord.StaticResources, serviceProvider, staticResourceWorker);
                    }
 
                    _baseDictionary.Add(value, keyRecord);
 
                    if (TraceResourceDictionary.IsEnabled) 
                    {
                        TraceResourceDictionary.TraceActivityItem( 
                            TraceResourceDictionary.SetKey,
                            this,
                            value);
                    } 

                } 
                else 
                {
                    throw new ArgumentException(SR.Get(SRID.KeyCollectionHasInvalidKey)); 
                }
            }

            // Notify owners of the HasImplicitStyles flag value 
            // but there is not need to fire an invalidation.
            NotifyOwners(new ResourcesChangeInfo(null, this)); 
        } 
Пример #7
0
        internal virtual object GetExtensionValue(
            IOptimizedMarkupExtension optimizedMarkupExtensionRecord,
            string                    propertyName)
        { 
            object innerExtensionValue = null;
            object valueObject = null; 
            short memberId = optimizedMarkupExtensionRecord.ValueId; 
            short extensionTypeId = optimizedMarkupExtensionRecord.ExtensionTypeId;
 
            switch (extensionTypeId)
            {
                case (short)KnownElements.StaticExtension:
                    valueObject = GetStaticExtensionValue(memberId); 
                    break;
 
                case (short)KnownElements.DynamicResourceExtension: 
                    innerExtensionValue = GetInnerExtensionValue(optimizedMarkupExtensionRecord);
                    valueObject = new DynamicResourceExtension(innerExtensionValue); 
                    break;

                case (short)KnownElements.StaticResourceExtension:
                    innerExtensionValue = GetInnerExtensionValue(optimizedMarkupExtensionRecord); 
                    valueObject = new StaticResourceExtension(innerExtensionValue);
                    break; 
            } 

            if (valueObject == null) 
            {
                string valueTypeName = string.Empty;

                switch (extensionTypeId) 
                {
                    case (short)KnownElements.StaticExtension: 
                        valueTypeName = typeof(StaticExtension).FullName; 
                        break;
                    case (short)KnownElements.DynamicResourceExtension: 
                        valueTypeName = typeof(DynamicResourceExtension).FullName;
                        break;
                    case (short)KnownElements.StaticResourceExtension:
                        valueTypeName = typeof(StaticResourceExtension).FullName; 
                        break;
                } 
 
                ThrowException(SRID.ParserCannotConvertPropertyValue, propertyName, valueTypeName);
            } 

            return valueObject;
        }
Пример #8
0
        // The end of the constructor parameter section has been reached.  Create an
        // instance of the object after finding the appropriate constructor and converting 
        // all of the objects held on the stack. 
        internal virtual void ReadConstructorParametersEndRecord()
        { 
            Type   elementType = ParentContext.ExpectedType;
            short  positiveElementTypeId = (short)-ParentContext.ExpectedTypeId;

            object param = null; 
            ArrayList paramList = null;
            int paramCount; 
            object instance = null; 
            bool foundInstance = false;
 
            if( TraceMarkup.IsEnabled )
            {
                TraceMarkup.Trace( TraceEventType.Start,
                                 TraceMarkup.CreateMarkupExtension, 
                                 elementType );
            } 
 
            if (CurrentContext.CheckFlag(ReaderFlags.SingletonConstructorParam))
            { 
                param = CurrentContext.ObjectData;
                paramCount = 1;

                // Fast code path for [static/dynamic] resource extensions & 
                // Type/Static/TemplateBinding extensions
                switch (positiveElementTypeId) 
                { 
                    case (short)KnownElements.TypeExtension:
 
                        // Note that this assumes that TypeExtension has a
                        // constructor with one param of type Type or String.
                        Type t = param as Type;
                        if (t != null) 
                        {
                            instance = new TypeExtension(t); 
                        } 
                        else
                        { 
                            Debug.Assert(param is String);
                            instance = new TypeExtension((String)param);
                        }
 
                        foundInstance = true;
                        break; 
 
                    case (short)KnownElements.StaticResourceExtension:
 
                        // Note that this assumes that StaticResourceExtension has a
                        // constructor with one param of type object.
                        instance = new StaticResourceExtension(param);
                        foundInstance = true; 
                        break;
 
                    case (short)KnownElements.DynamicResourceExtension: 

                        // Note that this assumes that DynamicResourceExtension has a 
                        // constructor with one param of type object.
                        instance = new DynamicResourceExtension(param);
                        foundInstance = true;
                        break; 

                    case (short)KnownElements.StaticExtension: 
 
                        // Note that this assumes that StaticExtension has a default
                        // constructor and one public property of type string and one 
                        // internal property of type object for optimized member info.
                        instance = new StaticExtension((string)param);
                        foundInstance = true;
                        break; 

                    case (short)KnownElements.TemplateBindingExtension: 
 
                        // Note that this assumes that TemplateBindingExtension has a
                        // constructor with one param of type DependencyProperty. If a 
                        // string is passed in due to there being other attributes like
                        // converter being set, then that needs to be converted now first.
                        DependencyProperty dp = param as DependencyProperty;
                        if (dp == null) 
                        {
                            string paramString = param as string; 
                            Type ownerType = ParserContext.TargetType; 
                            Debug.Assert(paramString != null);
 
                            dp = XamlTypeMapper.ParsePropertyName(ParserContext,
                                                                  paramString.Trim(),
                                                                  ref ownerType);
 
                            if (dp == null)
                            { 
                                ThrowException(SRID.ParserNoDPOnOwner, paramString, ownerType.FullName); 
                            }
                        } 

                        instance = new TemplateBindingExtension(dp);
                        foundInstance = true;
                        break; 
                }
            } 
            else 
            {
                paramList = (ArrayList)CurrentContext.ObjectData; 
                paramCount = paramList.Count;
            }

            if (!foundInstance) 
            {
                // Find the constructor based on the number of parameters stored in paramList 
                XamlTypeMapper.ConstructorData data = XamlTypeMapper.GetConstructors(elementType); 
                ConstructorInfo[] infos = data.Constructors;
                for (int i=0; i<infos.Length; i++) 
                {
                    ConstructorInfo info = infos[i];
                    ParameterInfo[] paramInfos = data.GetParameters(i);
                    if (paramInfos.Length == paramCount) 
                    {
                        object[] paramArray = new object[paramInfos.Length]; 
 
                        if (paramCount == 1)
                        { 
                            Debug.Assert(param != null && paramList == null, "Must have a single param");
                            ProcessConstructorParameter(paramInfos[0], param, ref paramArray[0]);

                            // Fast code path for other markupextensions 
                            if (positiveElementTypeId == (short)KnownElements.RelativeSource)
                            { 
                                // Note that this assumes that RelativeSource has a 
                                // constructor with one param of type RelativeSourceMode.
                                instance = new System.Windows.Data.RelativeSource((System.Windows.Data.RelativeSourceMode)paramArray[0]); 
                                foundInstance = true;
                            }
                        }
                        else 
                        {
                            Debug.Assert(param == null && paramList != null, "Must have a paramList"); 
 
                            // Check each type and attempt to convert the paramList using
                            // the type converter associated with each parameter type. 
                            for (int j=0; j<paramInfos.Length; j++)
                            {
                                ProcessConstructorParameter(paramInfos[j], paramList[j], ref paramArray[j]);
                            } 
                        }
 
                        if (!foundInstance) 
                        {
                            // If we make it to here we have a list of converted parameters, so 
                            // invoke the constructor with that list.
#if !STRESS
                            try
                            { 
#endif
                                instance = info.Invoke(paramArray); 
                                foundInstance = true; 
#if !STRESS
                            } 
                            catch (Exception e)
                            {
                                if (CriticalExceptions.IsCriticalException(e) || e is XamlParseException)
                                { 
                                    throw;
                                } 
 
                                TargetInvocationException tie = e as TargetInvocationException;
                                if( tie != null ) 
                                {
                                    e = tie.InnerException;
                                }
 
                                ThrowExceptionWithLine(SR.Get(SRID.ParserFailedToCreateFromConstructor, info.DeclaringType.Name),  e);
 
                            } 
#endif
                        } 
                    }
                }
            }
 
            if (foundInstance)
            { 
                ParentContext.ObjectData = instance; 
                ParentContext.ExpectedType = null;
                PopContext(); 
            }
            else
            {
                // If we get to here, then no matching constructor was found, so complain 
                ThrowException(SRID.ParserBadConstructorParams, elementType.Name, paramCount.ToString(CultureInfo.CurrentCulture));
            } 
 
            if( TraceMarkup.IsEnabled )
            { 
                TraceMarkup.Trace( TraceEventType.Stop,
                                 TraceMarkup.CreateMarkupExtension,
                                 elementType,
                                 instance ); 
            }
 
        }