// // System.ComponentModel.TypeDescriptor.cs // // Authors: // Gonzalo Paniagua Javier (gonzalo@ximian.com) // Andreas Nahr (ClassDevelopment@A-SoftTech.com) // // (C) 2002 Ximian, Inc (http://www.ximian.com) // (C) 2003 Andreas Nahr // using System; using System.Collections; using System.Reflection; using System.Globalization; using System.ComponentModel.Design; namespace System.ComponentModel { public sealed class TypeDescriptor { private static readonly string creatingDefaultConverters = "creatingDefaultConverters"; private static Hashtable defaultConverters; private static IComNativeDescriptorHandler descriptorHandler; private static Hashtable componentTable = new Hashtable (); private static Hashtable typeTable = new Hashtable (); private TypeDescriptor () { } [MonoTODO] public static void AddEditorTable (Type editorBaseType, Hashtable table) { throw new NotImplementedException (); } public static IDesigner CreateDesigner(IComponent component, Type designerBaseType) { string tn = designerBaseType.AssemblyQualifiedName; AttributeCollection col = GetAttributes (component); foreach (Attribute at in col) { DesignerAttribute dat = at as DesignerAttribute; if (dat != null && tn == dat.DesignerBaseTypeName) { return (IDesigner) Activator.CreateInstance (GetTypeFromName (component, dat.DesignerTypeName)); } } return null; } public static EventDescriptor CreateEvent (Type componentType, string name, Type type, Attribute [] attributes) { return new ReflectionEventDescriptor (componentType, name, type, attributes); } public static EventDescriptor CreateEvent (Type componentType, EventDescriptor oldEventDescriptor, Attribute [] attributes) { return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes); } public static PropertyDescriptor CreateProperty (Type componentType, string name, Type type, Attribute [] attributes) { return new ReflectionPropertyDescriptor (componentType, name, type, attributes); } public static PropertyDescriptor CreateProperty (Type componentType, PropertyDescriptor oldPropertyDescriptor, Attribute [] attributes) { return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes); } public static AttributeCollection GetAttributes (Type componentType) { if (componentType == null) return AttributeCollection.Empty; return GetTypeInfo (componentType).GetAttributes (); } public static AttributeCollection GetAttributes (object component) { return GetAttributes (component, false); } public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc) { if (component == null) return AttributeCollection.Empty; if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) { return ((ICustomTypeDescriptor) component).GetAttributes (); } else { IComponent com = component as IComponent; if (com != null) return GetComponentInfo (com).GetAttributes (); else return GetTypeInfo (component.GetType()).GetAttributes (); } } public static string GetClassName (object component) { return GetClassName (component, false); } public static string GetClassName (object component, bool noCustomTypeDesc) { if (component == null) throw new ArgumentNullException ("component", "component cannot be null"); if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) { return ((ICustomTypeDescriptor) component).GetClassName (); } else { return component.GetType ().FullName; } } public static string GetComponentName (object component) { return GetComponentName (component, false); } public static string GetComponentName (object component, bool noCustomTypeDesc) { if (component == null) throw new ArgumentNullException ("component", "component cannot be null"); if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) { return ((ICustomTypeDescriptor) component).GetComponentName (); } else { if (((IComponent) component).Site == null) return null; else return ((IComponent) component).Site.Name; } } public static TypeConverter GetConverter (object component) { return GetConverter (component.GetType ()); } public static TypeConverter GetConverter (object component, bool noCustomTypeDesc) { if (component == null) throw new ArgumentNullException ("component", "component cannot be null"); if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) { return ((ICustomTypeDescriptor) component).GetConverter (); } else { Type t = null; AttributeCollection atts = GetAttributes (component, false); TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)]; if (tca != null && tca.ConverterTypeName.Length > 0) { t = GetTypeFromName (component as IComponent, tca.ConverterTypeName); } Type primitive = component.GetType (); while (t == null && primitive != typeof (object)) { t = (Type) DefaultConverters [primitive]; if (t == null) primitive = primitive.BaseType; } if (t != null) return (TypeConverter) Activator.CreateInstance (t); else return null; } } private static Hashtable DefaultConverters { get { if (defaultConverters != null) return defaultConverters; lock (creatingDefaultConverters) { if (defaultConverters != null) return defaultConverters; defaultConverters = new Hashtable (); defaultConverters.Add (typeof (bool), typeof (BooleanConverter)); defaultConverters.Add (typeof (byte), typeof (ByteConverter)); defaultConverters.Add (typeof (sbyte), typeof (SByteConverter)); defaultConverters.Add (typeof (string), typeof (StringConverter)); defaultConverters.Add (typeof (char), typeof (CharConverter)); defaultConverters.Add (typeof (short), typeof (Int16Converter)); defaultConverters.Add (typeof (int), typeof (Int32Converter)); defaultConverters.Add (typeof (long), typeof (Int64Converter)); defaultConverters.Add (typeof (ushort), typeof (UInt16Converter)); defaultConverters.Add (typeof (uint), typeof (UInt32Converter)); defaultConverters.Add (typeof (ulong), typeof (UInt64Converter)); defaultConverters.Add (typeof (float), typeof (SingleConverter)); defaultConverters.Add (typeof (double), typeof (DoubleConverter)); defaultConverters.Add (typeof (decimal), typeof (DecimalConverter)); defaultConverters.Add (typeof (object), typeof (TypeConverter)); defaultConverters.Add (typeof (void), typeof (TypeConverter)); defaultConverters.Add (typeof (Array), typeof (ArrayConverter)); defaultConverters.Add (typeof (CultureInfo), typeof (CultureInfoConverter)); defaultConverters.Add (typeof (DateTime), typeof (DateTimeConverter)); defaultConverters.Add (typeof (Guid), typeof (GuidConverter)); defaultConverters.Add (typeof (TimeSpan), typeof (TimeSpanConverter)); defaultConverters.Add (typeof (ICollection), typeof (CollectionConverter)); //FIXME We need to add the type for the ReferenceConverter //defaultConverters.Add (typeof (????), typeof (ReferenceConverter)); } return defaultConverters; } } public static TypeConverter GetConverter (Type type) { if (type.IsEnum) { // EnumConverter needs to know the enum type return new EnumConverter(type); } else { TypeConverterAttribute tca = null; Type t = null; object [] atts = type.GetCustomAttributes (typeof(TypeConverterAttribute), true); if (atts.Length > 0) tca = (TypeConverterAttribute)atts[0]; if (tca != null) { t = GetTypeFromName (null, tca.ConverterTypeName); } Type primitive = type; while (t == null && primitive != typeof (object)) { t = (Type) DefaultConverters [primitive]; if (t == null) primitive = primitive.BaseType; } if (t != null) return (TypeConverter) Activator.CreateInstance (t); else return null; } } public static EventDescriptor GetDefaultEvent (Type componentType) { return GetTypeInfo (componentType).GetDefaultEvent (); } public static EventDescriptor GetDefaultEvent (object component) { return GetDefaultEvent (component, false); } public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc) { if (!noCustomTypeDesc && (component is ICustomTypeDescriptor)) return ((ICustomTypeDescriptor) component).GetDefaultEvent (); else { IComponent com = component as IComponent; if (com != null) return GetComponentInfo (com).GetDefaultEvent (); else return GetTypeInfo (component.GetType()).GetDefaultEvent (); } } public static PropertyDescriptor GetDefaultProperty (Type componentType) { return GetTypeInfo (componentType).GetDefaultProperty (); } public static PropertyDescriptor GetDefaultProperty (object component) { return GetDefaultProperty (component, false); } public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc) { if (!noCustomTypeDesc && (component is ICustomTypeDescriptor)) return ((ICustomTypeDescriptor) component).GetDefaultProperty (); else { IComponent com = component as IComponent; if (com != null) return GetComponentInfo (com).GetDefaultProperty (); else return GetTypeInfo (component.GetType()).GetDefaultProperty (); } } [MonoTODO] public static object GetEditor (Type componentType, Type editorBaseType) { throw new NotImplementedException (); } public static object GetEditor (object component, Type editorBaseType) { return GetEditor (component, editorBaseType, false); } [MonoTODO] public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc) { throw new NotImplementedException (); } public static EventDescriptorCollection GetEvents (object component) { return GetEvents (component, false); } public static EventDescriptorCollection GetEvents (Type componentType) { return GetEvents (componentType, null); } public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes) { return GetEvents (component, attributes, false); } public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc) { return GetEvents (component, null, noCustomTypeDesc); } public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes) { return GetTypeInfo (componentType).GetEvents (attributes); } public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc) { if (!noCustomTypeDesc && (component is ICustomTypeDescriptor)) return ((ICustomTypeDescriptor) component).GetEvents (attributes); else { IComponent com = component as IComponent; if (com != null) return GetComponentInfo (com).GetEvents (attributes); else return GetTypeInfo (component.GetType()).GetEvents (attributes); } } public static PropertyDescriptorCollection GetProperties (object component) { return GetProperties (component, false); } public static PropertyDescriptorCollection GetProperties (Type componentType) { return GetProperties (componentType, null); } public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes) { return GetProperties (component, attributes, false); } public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc) { if (!noCustomTypeDesc && (component is ICustomTypeDescriptor)) return ((ICustomTypeDescriptor) component).GetProperties (attributes); else { IComponent com = component as IComponent; if (com != null) return GetComponentInfo (com).GetProperties (attributes); else return GetTypeInfo (component.GetType()).GetProperties (attributes); } } public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc) { return GetProperties (component, null, noCustomTypeDesc); } public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes) { return GetTypeInfo (componentType).GetProperties (attributes); } public static void SortDescriptorArray (IList infos) { string[] names = new string [infos.Count]; object[] values = new object [infos.Count]; for (int n=0; n