File: cdf\src\NetFx40\Tools\System.Activities.Presentation\System\Activities\Presentation\Model\XamlUtilities.cs
Project: ndp\System.Data.csproj (System.Data)
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------
 
 
namespace System.Activities.Presentation.Model
{
 
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Reflection;
 
 
    internal static class XamlUtilities
    {
 
        static Hashtable converterCache;
        static object converterCacheSyncObject = new object();
 
        public static TypeConverter GetConverter(Type itemType)
        {
            TypeConverter converter = TypeDescriptor.GetConverter(itemType);
 
            if (converter == null || converter.GetType() == typeof(TypeConverter))
            {
 
                // We got an invalid converter.  WPF will do this if the converter
                // is internal, but we use internal converters all over the place
                // at design time.  Detect this and build the converter ourselves.
 
                if (converterCache != null)
                {
                    converter = (TypeConverter)converterCache[itemType];
                    if (converter != null)
                    {
                        return converter;
                    }
                }
 
                AttributeCollection attrs = TypeDescriptor.GetAttributes(itemType);
                TypeConverterAttribute tca = attrs[typeof(TypeConverterAttribute)] as TypeConverterAttribute;
                if (tca != null && tca.ConverterTypeName != null)
                {
                    Type type = Type.GetType(tca.ConverterTypeName);
                    if (type != null && !type.IsPublic && typeof(TypeConverter).IsAssignableFrom(type))
                    {
                        ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(Type) });
                        if (ctor != null)
                        {
                            converter = (TypeConverter)ctor.Invoke(new object[] { itemType });
                        }
                        else
                        {
                            converter = (TypeConverter)Activator.CreateInstance(type);
                        }
 
                        lock (converterCacheSyncObject)
                        {
                            if (converterCache == null)
                            {
                                converterCache = new Hashtable();
 
                                // Listen to type changes and clear the cache.
                                // This allows new metadata tables to be installed
 
                                TypeDescriptor.Refreshed += delegate(RefreshEventArgs args)
                                {
                                    converterCache.Remove(args.TypeChanged);
                                };
                            }
 
                            converterCache[itemType] = converter;
                        }
                    }
                }
            }
 
            return converter;
        }
    }
}