1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
6 namespace System.Activities.Presentation.Model
10 using System.Collections;
11 using System.ComponentModel;
12 using System.Reflection;
15 internal static class XamlUtilities
18 static Hashtable converterCache;
19 static object converterCacheSyncObject = new object();
21 public static TypeConverter GetConverter(Type itemType)
23 TypeConverter converter = TypeDescriptor.GetConverter(itemType);
25 if (converter == null || converter.GetType() == typeof(TypeConverter))
28 // We got an invalid converter. WPF will do this if the converter
29 // is internal, but we use internal converters all over the place
30 // at design time. Detect this and build the converter ourselves.
32 if (converterCache != null)
34 converter = (TypeConverter)converterCache[itemType];
35 if (converter != null)
41 AttributeCollection attrs = TypeDescriptor.GetAttributes(itemType);
42 TypeConverterAttribute tca = attrs[typeof(TypeConverterAttribute)] as TypeConverterAttribute;
43 if (tca != null && tca.ConverterTypeName != null)
45 Type type = Type.GetType(tca.ConverterTypeName);
46 if (type != null && !type.IsPublic && typeof(TypeConverter).IsAssignableFrom(type))
48 ConstructorInfo ctor = type.GetConstructor(new Type[] { typeof(Type) });
51 converter = (TypeConverter)ctor.Invoke(new object[] { itemType });
55 converter = (TypeConverter)Activator.CreateInstance(type);
58 lock (converterCacheSyncObject)
60 if (converterCache == null)
62 converterCache = new Hashtable();
64 // Listen to type changes and clear the cache.
65 // This allows new metadata tables to be installed
67 TypeDescriptor.Refreshed += delegate(RefreshEventArgs args)
69 converterCache.Remove(args.TypeChanged);
73 converterCache[itemType] = converter;