ThemeDictionaryExtension.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / ThemeDictionaryExtension.cs / 1 / ThemeDictionaryExtension.cs

                            /****************************************************************************\ 
*
* File: ThemeDictionaryExtension.cs
*
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 
 
using System;
using System.ComponentModel; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text; 
using System.Windows;
using System.Windows.Data; 
using System.Windows.Markup; 

 
namespace System.Windows
{
    /// 
    ///  ThemeDictionaryExtension allows application authors to customize 
    ///  control styles based on the current system theme.
    /// 
    ///  
    [MarkupExtensionReturnType(typeof(Uri))]
    public class ThemeDictionaryExtension : MarkupExtension 
    {
        #region Constructors

        ///  
        ///  Constructor that takes no parameters
        ///  
        public ThemeDictionaryExtension() 
        {
        } 

        /// 
        ///  Constructor that takes the name of the assembly that contains the themed ResourceDictionary.
        ///  
        public ThemeDictionaryExtension(string assemblyName)
        { 
            if (assemblyName != null) 
            {
                _assemblyName = assemblyName; 
            }
            else
            {
                throw new ArgumentNullException("assemblyName"); 
            }
        } 
 
        #endregion
 
        #region Public Properties

        /// 
        ///     The name of the assembly that contains the themed ResourceDictionary. 
        /// 
        public string AssemblyName 
        { 
            get { return _assemblyName; }
            set { _assemblyName = value; } 
        }

        #endregion
 
        #region Public Methods
 
        ///  
        ///  Return an object that should be set on the targetObject's targetProperty
        ///  for this markup extension.  For ThemeDictionaryExtension, this is the Uri 
        ///  pointing to theme specific dictionary in the specified assembly by AssemblyName.
        /// 
        /// ServiceProvider that can be queried for services.
        ///  
        ///  The object to set on this property.
        ///  
        public override object ProvideValue(IServiceProvider serviceProvider) 
        {
            if (string.IsNullOrEmpty(AssemblyName)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ThemeDictionaryExtension_Name));
            }
 
            IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if( provideValueTarget == null ) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.MarkupExtensionNoContext, GetType().Name, "IProvideValueTarget" ));
            } 

            object targetObject = provideValueTarget.TargetObject;
            object targetProperty = provideValueTarget.TargetProperty;
 
            ResourceDictionary dictionary = targetObject as ResourceDictionary;
            PropertyInfo propertyInfo = targetProperty as PropertyInfo; 
 
            // Allow targetProperty to be null or ResourceDictionary.Source
            if (dictionary == null || (targetProperty != null && propertyInfo != SourceProperty)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ThemeDictionaryExtension_Source));
            }
 
            Register(dictionary, _assemblyName);
 
            return GenerateUri(_assemblyName); 
        }
 
        // Build the Uri for the assembly:
        // /AssemblyName;Component/themes/..xaml
        private static Uri GenerateUri(string assemblyName)
        { 
            StringBuilder uri = new StringBuilder(assemblyName.Length + 50);
 
            uri.Append("/"); 
            uri.Append(assemblyName);
 
            // If assembly is PresentationFramework, append the Theme name
            if (assemblyName.Equals(SystemResources.PresentationFrameworkName, StringComparison.OrdinalIgnoreCase))
            {
                uri.Append('.'); 
                uri.Append(MS.Win32.UxThemeWrapper.ThemeName);
            } 
 
            uri.Append(";component/");
            uri.Append(SystemResources.ResourceDictionaries.ThemedResourceName); 
            uri.Append(".xaml");

            return new System.Uri(uri.ToString(), System.UriKind.RelativeOrAbsolute);
        } 

        #endregion 
 
        #region Data
 
        private string _assemblyName;

        #endregion
 
        #region Static Data
 
        // Keep track of all dictionaries that have ThemeDictionaryExtensions applied to them 
        // When the theme changes update the Source uri to point to the new theme info
 
        // This is the ResourceDictionary.Source property info
        private static PropertyInfo _sourceProperty;

        private static PropertyInfo SourceProperty 
        {
            get 
            { 
                if (_sourceProperty == null)
                { 
                    _sourceProperty = typeof(ResourceDictionary).GetProperty("Source");
                }
                return _sourceProperty;
            } 
        }
 
        private class ThemeDictionaryInfo 
        {
            public WeakReference DictionaryReference; 
            public string AssemblyName;
        }

        // Store a list of dictionaries and assembly info's. 
        // When the theme changes, give the dictionaries a new Source Uri
        private static List _themeDictionaryInfos; 
        private static object _themeDictionaryInfosLock = new object(); 

        private static void Register(ResourceDictionary dictionary, string assemblyName) 
        {
            Debug.Assert(dictionary != null, "dictionary should not be null");
            Debug.Assert(assemblyName != null, "assemblyName should not be null");
 
            lock (_themeDictionaryInfosLock)
            { 
                if (_themeDictionaryInfos == null) 
                {
                    _themeDictionaryInfos = new List(); 
                }
                ThemeDictionaryInfo info;

                for (int i = 0; i < _themeDictionaryInfos.Count; i++) 
                {
                    info = _themeDictionaryInfos[i]; 
 
                    if (!info.DictionaryReference.IsAlive)
                    { 
                        // Remove from list
                        _themeDictionaryInfos.RemoveAt(i);
                        i--;
                        continue; 
                    }
 
                    if (info.DictionaryReference.Target == dictionary) 
                    {
                        info.AssemblyName = assemblyName; 
                        return;
                    }
                }
 
                // Not present, add to list
                info = new ThemeDictionaryInfo(); 
                info.DictionaryReference = new WeakReference(dictionary); 
                info.AssemblyName = assemblyName;
 
                _themeDictionaryInfos.Add(info);
            }
        }
 
        internal static void OnThemeChanged()
        { 
            lock (_themeDictionaryInfosLock) 
            {
                // Update all resource dictionaries 

                if (_themeDictionaryInfos != null)
                {
                    for (int i = 0; i < _themeDictionaryInfos.Count; i++) 
                    {
                        ThemeDictionaryInfo info = _themeDictionaryInfos[i]; 
 
                        if (!info.DictionaryReference.IsAlive)
                        { 
                            // Remove from list
                            _themeDictionaryInfos.RemoveAt(i);
                            i--;
                            continue; 
                        }
 
                        // Provide the new dictionary URI 
                        ResourceDictionary dictionary = (ResourceDictionary)info.DictionaryReference.Target;
                        dictionary.Source = GenerateUri(info.AssemblyName); 
                    }
                }
            }
        } 

        #endregion 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: ThemeDictionaryExtension.cs
*
* Copyright (C) 2005 by Microsoft Corporation.  All rights reserved. 
*
\***************************************************************************/ 
 
using System;
using System.ComponentModel; 
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text; 
using System.Windows;
using System.Windows.Data; 
using System.Windows.Markup; 

 
namespace System.Windows
{
    /// 
    ///  ThemeDictionaryExtension allows application authors to customize 
    ///  control styles based on the current system theme.
    /// 
    ///  
    [MarkupExtensionReturnType(typeof(Uri))]
    public class ThemeDictionaryExtension : MarkupExtension 
    {
        #region Constructors

        ///  
        ///  Constructor that takes no parameters
        ///  
        public ThemeDictionaryExtension() 
        {
        } 

        /// 
        ///  Constructor that takes the name of the assembly that contains the themed ResourceDictionary.
        ///  
        public ThemeDictionaryExtension(string assemblyName)
        { 
            if (assemblyName != null) 
            {
                _assemblyName = assemblyName; 
            }
            else
            {
                throw new ArgumentNullException("assemblyName"); 
            }
        } 
 
        #endregion
 
        #region Public Properties

        /// 
        ///     The name of the assembly that contains the themed ResourceDictionary. 
        /// 
        public string AssemblyName 
        { 
            get { return _assemblyName; }
            set { _assemblyName = value; } 
        }

        #endregion
 
        #region Public Methods
 
        ///  
        ///  Return an object that should be set on the targetObject's targetProperty
        ///  for this markup extension.  For ThemeDictionaryExtension, this is the Uri 
        ///  pointing to theme specific dictionary in the specified assembly by AssemblyName.
        /// 
        /// ServiceProvider that can be queried for services.
        ///  
        ///  The object to set on this property.
        ///  
        public override object ProvideValue(IServiceProvider serviceProvider) 
        {
            if (string.IsNullOrEmpty(AssemblyName)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ThemeDictionaryExtension_Name));
            }
 
            IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if( provideValueTarget == null ) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.MarkupExtensionNoContext, GetType().Name, "IProvideValueTarget" ));
            } 

            object targetObject = provideValueTarget.TargetObject;
            object targetProperty = provideValueTarget.TargetProperty;
 
            ResourceDictionary dictionary = targetObject as ResourceDictionary;
            PropertyInfo propertyInfo = targetProperty as PropertyInfo; 
 
            // Allow targetProperty to be null or ResourceDictionary.Source
            if (dictionary == null || (targetProperty != null && propertyInfo != SourceProperty)) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ThemeDictionaryExtension_Source));
            }
 
            Register(dictionary, _assemblyName);
 
            return GenerateUri(_assemblyName); 
        }
 
        // Build the Uri for the assembly:
        // /AssemblyName;Component/themes/..xaml
        private static Uri GenerateUri(string assemblyName)
        { 
            StringBuilder uri = new StringBuilder(assemblyName.Length + 50);
 
            uri.Append("/"); 
            uri.Append(assemblyName);
 
            // If assembly is PresentationFramework, append the Theme name
            if (assemblyName.Equals(SystemResources.PresentationFrameworkName, StringComparison.OrdinalIgnoreCase))
            {
                uri.Append('.'); 
                uri.Append(MS.Win32.UxThemeWrapper.ThemeName);
            } 
 
            uri.Append(";component/");
            uri.Append(SystemResources.ResourceDictionaries.ThemedResourceName); 
            uri.Append(".xaml");

            return new System.Uri(uri.ToString(), System.UriKind.RelativeOrAbsolute);
        } 

        #endregion 
 
        #region Data
 
        private string _assemblyName;

        #endregion
 
        #region Static Data
 
        // Keep track of all dictionaries that have ThemeDictionaryExtensions applied to them 
        // When the theme changes update the Source uri to point to the new theme info
 
        // This is the ResourceDictionary.Source property info
        private static PropertyInfo _sourceProperty;

        private static PropertyInfo SourceProperty 
        {
            get 
            { 
                if (_sourceProperty == null)
                { 
                    _sourceProperty = typeof(ResourceDictionary).GetProperty("Source");
                }
                return _sourceProperty;
            } 
        }
 
        private class ThemeDictionaryInfo 
        {
            public WeakReference DictionaryReference; 
            public string AssemblyName;
        }

        // Store a list of dictionaries and assembly info's. 
        // When the theme changes, give the dictionaries a new Source Uri
        private static List _themeDictionaryInfos; 
        private static object _themeDictionaryInfosLock = new object(); 

        private static void Register(ResourceDictionary dictionary, string assemblyName) 
        {
            Debug.Assert(dictionary != null, "dictionary should not be null");
            Debug.Assert(assemblyName != null, "assemblyName should not be null");
 
            lock (_themeDictionaryInfosLock)
            { 
                if (_themeDictionaryInfos == null) 
                {
                    _themeDictionaryInfos = new List(); 
                }
                ThemeDictionaryInfo info;

                for (int i = 0; i < _themeDictionaryInfos.Count; i++) 
                {
                    info = _themeDictionaryInfos[i]; 
 
                    if (!info.DictionaryReference.IsAlive)
                    { 
                        // Remove from list
                        _themeDictionaryInfos.RemoveAt(i);
                        i--;
                        continue; 
                    }
 
                    if (info.DictionaryReference.Target == dictionary) 
                    {
                        info.AssemblyName = assemblyName; 
                        return;
                    }
                }
 
                // Not present, add to list
                info = new ThemeDictionaryInfo(); 
                info.DictionaryReference = new WeakReference(dictionary); 
                info.AssemblyName = assemblyName;
 
                _themeDictionaryInfos.Add(info);
            }
        }
 
        internal static void OnThemeChanged()
        { 
            lock (_themeDictionaryInfosLock) 
            {
                // Update all resource dictionaries 

                if (_themeDictionaryInfos != null)
                {
                    for (int i = 0; i < _themeDictionaryInfos.Count; i++) 
                    {
                        ThemeDictionaryInfo info = _themeDictionaryInfos[i]; 
 
                        if (!info.DictionaryReference.IsAlive)
                        { 
                            // Remove from list
                            _themeDictionaryInfos.RemoveAt(i);
                            i--;
                            continue; 
                        }
 
                        // Provide the new dictionary URI 
                        ResourceDictionary dictionary = (ResourceDictionary)info.DictionaryReference.Target;
                        dictionary.Source = GenerateUri(info.AssemblyName); 
                    }
                }
            }
        } 

        #endregion 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK