Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / ResourceDictionary.cs / 1586720 / ResourceDictionary.cs
/****************************************************************************\ * * File: ResourceDictionary.cs * * Dictionary that holds Resources for Framework components. * * Copyright (C) 2003 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using System; using System.IO; using System.Net; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics; using System.ComponentModel; using System.Security; using System.Windows.Threading; using System.Windows.Media; using System.IO.Packaging; using MS.Internal.IO.Packaging; // for PackageCacheEntry using System.Globalization; using System.Windows.Navigation; using MS.Internal; using MS.Internal.Utility; using MS.Internal.AppModel; using MS.Utility; using System.Xaml; using System.Xaml.Permissions; using System.Windows.Baml2006; using System.Windows.Markup; namespace System.Windows { ////// Dictionary that holds Resources for Framework components. /// [Localizability(LocalizationCategory.Ignore)] [Ambient] [UsableDuringInitialization(true)] public class ResourceDictionary : IDictionary, ISupportInitialize, System.Windows.Markup.IUriContext, System.Windows.Markup.INameScope { #region Constructor ////// Constructor for ResourceDictionary /// public ResourceDictionary() { _baseDictionary = new Hashtable(); IsThemeDictionary = SystemResources.IsSystemResourcesParsing; } #endregion Constructor #region PublicAPIs ////// Copies the dictionary's elements to a one-dimensional /// Array instance at the specified index. /// /// /// The one-dimensional Array that is the destination of the /// DictionaryEntry objects copied from Hashtable. The Array /// must have zero-based indexing. /// /// /// The zero-based index in array at which copying begins. /// public void CopyTo(DictionaryEntry[] array, int arrayIndex) { if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { CopyToWithoutLock(array, arrayIndex); } } else { CopyToWithoutLock(array, arrayIndex); } } private void CopyToWithoutLock(DictionaryEntry[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } _baseDictionary.CopyTo(array, arrayIndex); int length = arrayIndex + Count; for (int i = arrayIndex; i < length; i++) { DictionaryEntry entry = array[i]; object value = entry.Value; bool canCache; if (RealizeDeferContent(entry.Key, ref value, out canCache)) { entry.Value = value; } } } ////// List of ResourceDictionaries merged into this Resource Dictionary /// public CollectionMergedDictionaries { get { if (_mergedDictionaries == null) { _mergedDictionaries = new ResourceDictionaryCollection(this); _mergedDictionaries.CollectionChanged += OnMergedDictionariesChanged; } return _mergedDictionaries; } } /// /// Uri to load this resource from, it will clear the current state of the ResourceDictionary /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Uri Source { get { return _source; } set { if (value == null || String.IsNullOrEmpty(value.OriginalString)) { throw new ArgumentException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, value == null ? "''" : value.ToString())); } _source = value; Clear(); Uri uri = BindUriHelper.GetResolvedUri(_baseUri, _source); WebRequest request = WpfWebRequestHelper.CreateRequest(uri); WpfWebRequestHelper.ConfigCachePolicy(request, false); ContentType contentType = null; Stream s = null; try { s = WpfWebRequestHelper.GetResponseStream(request, out contentType); } catch (System.IO.IOException) { if (IsSourcedFromThemeDictionary) { switch (_fallbackState) { case FallbackState.Classic: { _fallbackState = FallbackState.Generic; Uri classicResourceUri = ThemeDictionaryExtension.GenerateFallbackUri(this, SystemResources.ClassicResourceName); Debug.Assert(classicResourceUri != null); Source = classicResourceUri; // After this recursive call has returned we are sure // that we have tried all fallback paths and so now // reset the _fallbackState _fallbackState = FallbackState.Classic; } break; case FallbackState.Generic: { _fallbackState = FallbackState.None; Uri genericResourceUri = ThemeDictionaryExtension.GenerateFallbackUri(this, SystemResources.GenericResourceName); Debug.Assert(genericResourceUri != null); Source = genericResourceUri; } break; } return; } else { throw; } } // MimeObjectFactory.GetObjectAndCloseStream will try to find the object converter basing on the mime type. // It can be a [....]/async converter. It's the converter's responsiblity to close the stream. // If it fails to find a convert, this call will return null. System.Windows.Markup.XamlReader asyncObjectConverter; ResourceDictionary loadedRD = MimeObjectFactory.GetObjectAndCloseStream(s, contentType, uri, false, false, false /*allowAsync*/, false /*isJournalNavigation*/, out asyncObjectConverter) as ResourceDictionary; if (loadedRD == null) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, _source.ToString())); } // ReferenceCopy all the key-value pairs in the _baseDictionary _baseDictionary = loadedRD._baseDictionary; // ReferenceCopy all the entries in the MergedDictionaries collection _mergedDictionaries = loadedRD._mergedDictionaries; // ReferenceCopy all of the deferred content state CopyDeferredContentFrom(loadedRD); // Copy over the HasImplicitStyles flag HasImplicitStyles = loadedRD.HasImplicitStyles; if (!IsInitializePending) { // Fire Invalidations for the changes made by asigning a new Source NotifyOwners(new ResourcesChangeInfo(null, this)); } } } #region INameScope ////// Registers the name - element combination /// /// name of the element /// Element where name is defined public void RegisterName(string name, object scopedElement) { throw new NotSupportedException(SR.Get(SRID.NamesNotSupportedInsideResourceDictionary)); } ////// Unregisters the name - element combination /// /// Name of the element public void UnregisterName(string name) { // Do Nothing as Names cannot be registered on ResourceDictionary } ////// Find the element given name /// /// Name of the element ///null always public object FindName(string name) { return null; } #endregion INameScope #region IUriContext ////// Accessor for the base uri of the ResourceDictionary /// Uri System.Windows.Markup.IUriContext.BaseUri { get { return _baseUri; } set { _baseUri = value; } } #endregion IUriContext #endregion PublicAPIs #region IDictionary ////// Gets a value indicating whether the IDictionary has a fixed size. /// public bool IsFixedSize { get { return _baseDictionary.IsFixedSize; } } ////// Gets a value indicating whether the ResourceDictionary is read-only. /// public bool IsReadOnly { get { return ReadPrivateFlag(PrivateFlags.IsReadOnly); } internal set { WritePrivateFlag(PrivateFlags.IsReadOnly, value); if (value == true) { // Seal all the styles and templates in this dictionary SealValues(); } // Set all the merged resource dictionaries as ReadOnly if (_mergedDictionaries != null) { for (int i = 0; i < _mergedDictionaries.Count; i++) { _mergedDictionaries[i].IsReadOnly = value; } } } } ////// Gets or sets the value associated with the specified key. /// ////// Fire Invalidations only for changes made after the Init Phase /// If the key is not found on this ResourceDictionary, it will look on any MergedDictionaries for it /// public object this[object key] { get { bool canCache; return GetValue(key, out canCache); } set { // Seal styles and templates within App and Theme dictionary SealValue(value); if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { SetValueWithoutLock(key, value); } } else { SetValueWithoutLock(key, value); } } } // This should only be called in the deferred BAML loading scenario. We // cache all the data that we need away and then get rid of the actual object. // No one needs to actually get this property so we're returning null. This // property has to be public since the XAML parser cannot set this internal // property in this scenario. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public DeferrableContent DeferrableContent { get { return null; } set { this.SetDeferrableContent(value); } } private void SetValueWithoutLock(object key, object value) { if (IsReadOnly) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); } object oldValue = _baseDictionary[key]; if (oldValue != value) { // We need to validate all the deferred references that refer // to the old resource before we overwrite it. ValidateDeferredResourceReferences(key); if( TraceResourceDictionary.IsEnabled ) { TraceResourceDictionary.Trace( TraceEventType.Start, TraceResourceDictionary.AddResource, this, key, value ); } _baseDictionary[key] = value; // Update the HasImplicitStyles flag UpdateHasImplicitStyles(key); // Notify owners of the change and fire invalidate if already initialized NotifyOwners(new ResourcesChangeInfo(key)); if( TraceResourceDictionary.IsEnabled ) { TraceResourceDictionary.Trace( TraceEventType.Stop, TraceResourceDictionary.AddResource, this, key, value ); } } } internal object GetValue(object key, out bool canCache) { if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { return GetValueWithoutLock(key, out canCache); } } else { return GetValueWithoutLock(key, out canCache); } } private object GetValueWithoutLock(object key, out bool canCache) { object value = _baseDictionary[key]; if (value != null) { RealizeDeferContent(key, ref value, out canCache); } else { canCache = true; //Search for the value in the Merged Dictionaries if (_mergedDictionaries != null) { for (int i = MergedDictionaries.Count - 1; (i > -1); i--) { // Note that MergedDictionaries collection can also contain null values ResourceDictionary mergedDictionary = MergedDictionaries[i]; if (mergedDictionary != null) { value = mergedDictionary.GetValue(key, out canCache); if (value != null) { break; } } } } } return value; } // Gets the type of the value stored at the given key internal Type GetValueType(object key, out bool found) { found = false; Type valueType = null; object value = _baseDictionary[key]; if (value != null) { found = true; KeyRecord keyRecord = value as KeyRecord; if (keyRecord != null) { Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); valueType = GetTypeOfFirstObject(keyRecord); } else { valueType = value.GetType(); } } else { // Search for the value in the Merged Dictionaries if (_mergedDictionaries != null) { for (int i = MergedDictionaries.Count - 1; (i > -1); i--) { // Note that MergedDictionaries collection can also contain null values ResourceDictionary mergedDictionary = MergedDictionaries[i]; if (mergedDictionary != null) { valueType = mergedDictionary.GetValueType(key, out found); if (found) { break; } } } } } return valueType; } ////// Gets a copy of the ICollection containing the keys of the IDictionary. /// public ICollection Keys { get { object[] keysCollection = new object[Count]; _baseDictionary.Keys.CopyTo(keysCollection, 0); return keysCollection; } } ////// Gets an ICollection containing the values in the Hashtable /// ///An ICollection containing the values in the Hashtable public ICollection Values { get { return new ResourceValuesCollection(this); } } ////// Adds an entry /// ////// Fire Invalidations only for changes made after the Init Phase /// public void Add(object key, object value) { // Seal styles and templates within App and Theme dictionary SealValue(value); if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { AddWithoutLock(key, value); } } else { AddWithoutLock(key, value); } } private void AddWithoutLock(object key, object value) { if (IsReadOnly) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); } if( TraceResourceDictionary.IsEnabled ) { TraceResourceDictionary.Trace( TraceEventType.Start, TraceResourceDictionary.AddResource, this, key, value ); } _baseDictionary.Add(key, value); // Update the HasImplicitKey flag UpdateHasImplicitStyles(key); // Notify owners of the change and fire invalidate if already initialized NotifyOwners(new ResourcesChangeInfo(key)); if( TraceResourceDictionary.IsEnabled ) { TraceResourceDictionary.Trace( TraceEventType.Stop, TraceResourceDictionary.AddResource, this, key, value ); } } ////// Removes all elements from the IDictionary. /// public void Clear() { if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { ClearWithoutLock(); } } else { ClearWithoutLock(); } } private void ClearWithoutLock() { if (IsReadOnly) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); } if (Count > 0) { // We need to validate all the deferred references that refer // to the old resource before we clear it. ValidateDeferredResourceReferences(null); // remove inheritance context from all values that got it from // this dictionary RemoveInheritanceContextFromValues(); _baseDictionary.Clear(); // Notify owners of the change and fire invalidate if already initialized NotifyOwners(ResourcesChangeInfo.CatastrophicDictionaryChangeInfo); } } ////// Determines whether the IDictionary contains an element with the specified key. /// if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too /// public bool Contains(object key) { bool result = _baseDictionary.Contains(key); if (result) { KeyRecord keyRecord = _baseDictionary[key] as KeyRecord; if (keyRecord != null && _deferredLocationList.Contains(keyRecord)) { return false; } } //Search for the value in the Merged Dictionaries if (_mergedDictionaries != null) { for (int i = MergedDictionaries.Count - 1; (i > -1) && !result; i--) { // Note that MergedDictionaries collection can also contain null values ResourceDictionary mergedDictionary = MergedDictionaries[i]; if (mergedDictionary != null) { result = mergedDictionary.Contains(key); } } } return result; } ////// Determines whether the IDictionary contains a BamlObjectFactory against the specified key. /// if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too /// private bool ContainsBamlObjectFactory(object key) { return GetBamlObjectFactory(key) != null; } ////// Retrieves a KeyRecord from the IDictionary using the specified key. /// If the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too /// private KeyRecord GetBamlObjectFactory(object key) { if (_baseDictionary.Contains(key)) { return _baseDictionary[key] as KeyRecord; } //Search for the value in the Merged Dictionaries if (_mergedDictionaries != null) { for (int i = MergedDictionaries.Count - 1; i > -1; i--) { // Note that MergedDictionaries collection can also contain null values ResourceDictionary mergedDictionary = MergedDictionaries[i]; if (mergedDictionary != null) { KeyRecord keyRecord = mergedDictionary.GetBamlObjectFactory(key); if (keyRecord != null) { return keyRecord; } } } } return null; } ////// Returns an IDictionaryEnumerator that can iterate through the Hashtable /// ///An IDictionaryEnumerator for the Hashtable public IDictionaryEnumerator GetEnumerator() { return new ResourceDictionaryEnumerator(this); } ////// Removes an entry /// ////// Fire Invalidations only for changes made after the Init Phase /// public void Remove(object key) { if (CanBeAccessedAcrossThreads) { lock(((ICollection)this).SyncRoot) { RemoveWithoutLock(key); } } else { RemoveWithoutLock(key); } } private void RemoveWithoutLock(object key) { if (IsReadOnly) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); } // We need to validate all the deferred references that refer // to the old resource before we remove it. ValidateDeferredResourceReferences(key); // remove the inheritance context from the value, if it came from // this dictionary RemoveInheritanceContext(_baseDictionary[key]); _baseDictionary.Remove(key); // Notify owners of the change and fire invalidate if already initialized NotifyOwners(new ResourcesChangeInfo(key)); } #endregion IDictionary #region ICollection ////// Gets the number of elements contained in the ICollection. /// public int Count { get { return _baseDictionary.Count; } } ////// Gets a value indicating whether access to the ICollection is synchronized (thread-safe). /// bool ICollection.IsSynchronized { get { return _baseDictionary.IsSynchronized; } } ////// Gets an object that can be used to synchronize access to the ICollection. /// object ICollection.SyncRoot { get { if (CanBeAccessedAcrossThreads) { // Notice that we are acquiring the ThemeDictionaryLock. This // is because the _parserContext used for template expansion // shares data-structures such as the BamlMapTable and // XamlTypeMapper with the parent ParserContext that was used // to build the template in the first place. So if this template // is from the App.Resources then the ParserContext that is used for // loading deferred content in the app dictionary and the // _parserContext used to load template content share the same // instances of BamlMapTable and XamlTypeMapper. Hence we need to // make sure that we lock on the same object inorder to serialize // access to these data-structures in multi-threaded scenarios. // Look at comment in Frameworktemplate.LoadContent to understand // why we use the ThemeDictionaryLock for template expansion. return SystemResources.ThemeDictionaryLock; } else { return _baseDictionary.SyncRoot; } } } ////// Copies the dictionary's elements to a one-dimensional /// Array instance at the specified index. /// /// /// The one-dimensional Array that is the destination of the /// DictionaryEntry objects copied from Hashtable. The Array /// must have zero-based indexing. /// /// /// The zero-based index in array at which copying begins. /// void ICollection.CopyTo(Array array, int arrayIndex) { CopyTo(array as DictionaryEntry[], arrayIndex); } #endregion ICollection #region IEnumerable IEnumerator IEnumerable.GetEnumerator() { return ((IDictionary)this).GetEnumerator(); } #endregion IEnumerable #region ISupportInitialize ////// Mark the begining of the Init phase /// ////// BeginInit and EndInit follow a transaction model. BeginInit marks the /// dictionary uninitialized and EndInit marks it initialized. /// public void BeginInit() { // Nested BeginInits on the same instance aren't permitted if (IsInitializePending) { throw new InvalidOperationException(SR.Get(SRID.NestedBeginInitNotSupported)); } IsInitializePending = true; IsInitialized = false; } ////// Fire Invalidation at the end of Init phase /// ////// BeginInit and EndInit follow a transaction model. BeginInit marks the /// dictionary uninitialized and EndInit marks it initialized. /// public void EndInit() { // EndInit without a BeginInit isn't permitted if (!IsInitializePending) { throw new InvalidOperationException(SR.Get(SRID.EndInitWithoutBeginInitNotSupported)); } Debug.Assert(IsInitialized == false, "Dictionary should not be initialized when EndInit is called"); IsInitializePending = false; IsInitialized = true; // Fire Invalidations collectively for all changes made during the Init Phase NotifyOwners(new ResourcesChangeInfo(null, this)); } #endregion ISupportInitialize #region DeferContent private bool CanCache(KeyRecord keyRecord, object value) { if (keyRecord.SharedSet) { return keyRecord.Shared; } else { return true; } } private bool RealizeDeferContent(object key, ref object value, out bool canCache) { KeyRecord keyRecord = value as KeyRecord; // If the value is not a key record then // it has already been realized, is not deferred and is a "ready to go" value. if (keyRecord == null) { canCache = true; return false; /* Not deferred content */ } Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); // We want to return null if a resource asks for itself. It should return null // should not find itself if (_deferredLocationList.Contains(keyRecord)) { canCache = false; value = null; return false; /* Not defered content */ } _deferredLocationList.Add(keyRecord); try { if (TraceResourceDictionary.IsEnabled) { TraceResourceDictionary.Trace( TraceEventType.Start, TraceResourceDictionary.RealizeDeferContent, this, key, value); } value = CreateObject(keyRecord); } finally { if (TraceResourceDictionary.IsEnabled) { TraceResourceDictionary.Trace( TraceEventType.Stop, TraceResourceDictionary.RealizeDeferContent, this, key, value); } } _deferredLocationList.Remove(keyRecord); if (key != null) { canCache = CanCache(keyRecord, value); if (canCache) { // Seal styles and templates within App and Theme dictionary SealValue(value); _numDefer--; _baseDictionary[key] = value; if (_numDefer == 0) { CloseReader(); } } return true; /* yes deferred content */ } else { canCache = true; return true; /* yes deferred content */ } } ////// Add a byte array that contains deferable content /// ////// Critical: sets critical fields _reader and _xamlLoadPermission. /// Safe: data comes from DeferrableContent, where it is critical to set /// [SecurityTreatAsSafe, SecurityCritical] private void SetDeferrableContent(DeferrableContent deferrableContent) { Debug.Assert(deferrableContent.Stream != null); Debug.Assert(deferrableContent.SchemaContext != null); Debug.Assert(deferrableContent.ObjectWriterFactory != null); Debug.Assert(deferrableContent.ServiceProvider != null); Debug.Assert(deferrableContent.RootObject != null); Baml2006ReaderSettings settings = new Baml2006ReaderSettings(deferrableContent.SchemaContext.Settings); settings.IsBamlFragment = true; settings.OwnsStream = true; settings.BaseUri = null; // Base URI can only be set on the root object, not on deferred content. Baml2006Reader reader = new Baml2006Reader(deferrableContent.Stream, deferrableContent.SchemaContext, settings); _objectWriterFactory = deferrableContent.ObjectWriterFactory; _objectWriterSettings = deferrableContent.ObjectWriterParentSettings; _deferredLocationList = new List(); _rootElement = deferrableContent.RootObject; IList keys = reader.ReadKeys(); // If we already have the Source set then we can ignore // this deferable content section if (_source == null) { if (_reader == null) { _reader = reader; _xamlLoadPermission = deferrableContent.LoadPermission; SetKeys(keys, deferrableContent.ServiceProvider); } else { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDuplicateDeferredContent)); } } else if (keys.Count > 0) { throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDeferredContentFailure)); } } private object GetKeyValue(KeyRecord key, IServiceProvider serviceProvider) { if (key.KeyString != null) { return key.KeyString; } else if (key.KeyType != null) { return key.KeyType; } else { System.Xaml.XamlReader reader = key.KeyNodeList.GetReader(); object value = EvaluateMarkupExtensionNodeList(reader, serviceProvider); return value; } } private object EvaluateMarkupExtensionNodeList(System.Xaml.XamlReader reader, IServiceProvider serviceProvider) { System.Xaml.XamlObjectWriter writer = _objectWriterFactory.GetXamlObjectWriter(null); System.Xaml.XamlServices.Transform(reader, writer); object value = writer.Result; MarkupExtension me = value as MarkupExtension; if (me != null) { value = me.ProvideValue(serviceProvider); } return value; } private object GetStaticResourceKeyValue(StaticResource staticResource, IServiceProvider serviceProvider) { System.Xaml.XamlReader reader = staticResource.ResourceNodeList.GetReader(); XamlType xamlTypeStaticResourceExtension = reader.SchemaContext.GetXamlType(typeof(StaticResourceExtension)); XamlMember xamlMemberResourceKey = xamlTypeStaticResourceExtension.GetMember("ResourceKey"); reader.Read(); if (reader.NodeType == Xaml.XamlNodeType.StartObject && reader.Type == xamlTypeStaticResourceExtension) { reader.Read(); // Skip Members that aren't _PositionalParameters or ResourceKey while (reader.NodeType == Xaml.XamlNodeType.StartMember && (reader.Member != XamlLanguage.PositionalParameters && reader.Member != xamlMemberResourceKey)) { reader.Skip(); } // Process the Member Value of _PositionParameters or ResourceKey if (reader.NodeType == Xaml.XamlNodeType.StartMember) { object value = null; reader.Read(); if (reader.NodeType == Xaml.XamlNodeType.StartObject) { System.Xaml.XamlReader subReader = reader.ReadSubtree(); value = EvaluateMarkupExtensionNodeList(subReader, serviceProvider); } else if (reader.NodeType == Xaml.XamlNodeType.Value) { value = reader.Value; } return value; } } return null; } private void SetKeys(IList 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)); } /// /// 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. /// // 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
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XmlCustomFormatter.cs
- MultiSelectRootGridEntry.cs
- RequestSecurityTokenResponseCollection.cs
- SystemIPv4InterfaceProperties.cs
- WorkflowServiceAttributesTypeConverter.cs
- MetadataPropertyAttribute.cs
- EncoderExceptionFallback.cs
- DataBindingCollection.cs
- RemotingConfigParser.cs
- ProxyElement.cs
- Section.cs
- DataControlButton.cs
- EditingMode.cs
- MaskDescriptors.cs
- WorkItem.cs
- _NestedSingleAsyncResult.cs
- WindowsFont.cs
- PlaceHolder.cs
- xdrvalidator.cs
- TextEditorDragDrop.cs
- SQLDecimal.cs
- FontWeight.cs
- QuaternionRotation3D.cs
- COM2IDispatchConverter.cs
- InkCanvas.cs
- ViewGenerator.cs
- EncodingStreamWrapper.cs
- FileEnumerator.cs
- Unit.cs
- FileDetails.cs
- DataGridViewSelectedCellsAccessibleObject.cs
- MailAddressCollection.cs
- ImageDrawing.cs
- PTConverter.cs
- SQLInt32.cs
- StringFunctions.cs
- BlurBitmapEffect.cs
- StylusPointPropertyInfo.cs
- XmlSchemaExporter.cs
- Figure.cs
- DrawingImage.cs
- HMACSHA1.cs
- SoapAttributes.cs
- Tokenizer.cs
- SurrogateEncoder.cs
- IdentitySection.cs
- FullTrustAssemblyCollection.cs
- RuleRefElement.cs
- HttpValueCollection.cs
- ChannelBuilder.cs
- HScrollProperties.cs
- MaterialGroup.cs
- Vector3DValueSerializer.cs
- EnvelopedPkcs7.cs
- ListBindingConverter.cs
- BaseAutoFormat.cs
- SpoolingTask.cs
- StateMachineExecutionState.cs
- InstancePersistenceEvent.cs
- LinearGradientBrush.cs
- FillErrorEventArgs.cs
- SystemNetworkInterface.cs
- HtmlTitle.cs
- MemberInitExpression.cs
- ContentElementAutomationPeer.cs
- FixedFlowMap.cs
- ObservableDictionary.cs
- PagerSettings.cs
- SqlReorderer.cs
- Condition.cs
- BinaryReader.cs
- ChildChangedEventArgs.cs
- DataPager.cs
- WebBrowser.cs
- ServiceModelExtensionCollectionElement.cs
- UnicastIPAddressInformationCollection.cs
- GraphicsPathIterator.cs
- DrawToolTipEventArgs.cs
- HttpContextServiceHost.cs
- TypeElementCollection.cs
- Size3DConverter.cs
- ColumnMap.cs
- pingexception.cs
- ClientRuntimeConfig.cs
- TreeIterators.cs
- WindowsStartMenu.cs
- ForeignConstraint.cs
- NetworkCredential.cs
- UTF32Encoding.cs
- CustomCategoryAttribute.cs
- Boolean.cs
- StaticTextPointer.cs
- ToolStripItemImageRenderEventArgs.cs
- WebPartManagerInternals.cs
- XhtmlBasicPanelAdapter.cs
- CryptoConfig.cs
- SqlClientWrapperSmiStream.cs
- DateTimeFormatInfo.cs
- DataColumnPropertyDescriptor.cs
- WebServiceTypeData.cs