2 // System.ComponentModel.TypeDescriptor.cs
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // (C) 2002 Ximian, Inc (http://www.ximian.com)
9 // (C) 2003 Andreas Nahr
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Reflection;
35 using System.Globalization;
36 using System.ComponentModel.Design;
37 using System.Security.Permissions;
39 namespace System.ComponentModel
42 public sealed class TypeDescriptor
44 private static readonly object creatingDefaultConverters = new object ();
45 private static Hashtable defaultConverters;
46 private static IComNativeDescriptorHandler descriptorHandler;
47 private static Hashtable componentTable = new Hashtable ();
48 private static Hashtable typeTable = new Hashtable ();
49 private static Hashtable editors;
51 private TypeDescriptor ()
56 [MonoNotSupported ("")]
57 [EditorBrowsable (EditorBrowsableState.Advanced)]
58 public static Type ComObjectType {
59 get { throw new NotImplementedException (); }
62 [MonoNotSupported("")]
63 [EditorBrowsable (EditorBrowsableState.Advanced)]
64 public static TypeDescriptionProvider AddAttributes (object instance, params Attribute [] attributes)
66 throw new NotImplementedException ();
69 [MonoNotSupported("")]
70 [EditorBrowsable (EditorBrowsableState.Advanced)]
71 public static TypeDescriptionProvider AddAttributes (Type type, params Attribute [] attributes)
73 throw new NotImplementedException ();
76 [MonoNotSupported("")]
77 [EditorBrowsable (EditorBrowsableState.Advanced)]
78 public static void AddProvider (TypeDescriptionProvider provider, object instance)
80 throw new NotImplementedException ();
83 [MonoNotSupported("")]
84 [EditorBrowsable (EditorBrowsableState.Advanced)]
85 public static void AddProvider (TypeDescriptionProvider provider, Type type)
87 throw new NotImplementedException ();
90 [MonoNotSupported("")]
91 public static object CreateInstance (IServiceProvider provider, Type objectType, Type [] argTypes, object [] args)
93 throw new NotImplementedException ();
98 [EditorBrowsable (EditorBrowsableState.Advanced)]
100 public static void AddEditorTable (Type editorBaseType, Hashtable table)
103 editors = new Hashtable ();
105 editors [editorBaseType] = table;
108 public static IDesigner CreateDesigner(IComponent component, Type designerBaseType)
110 string tn = designerBaseType.AssemblyQualifiedName;
111 AttributeCollection col = GetAttributes (component);
113 foreach (Attribute at in col) {
114 DesignerAttribute dat = at as DesignerAttribute;
115 if (dat != null && tn == dat.DesignerBaseTypeName) {
116 return (IDesigner) Activator.CreateInstance (GetTypeFromName (component, dat.DesignerTypeName));
123 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
124 public static EventDescriptor CreateEvent (Type componentType,
127 params Attribute [] attributes)
129 return new ReflectionEventDescriptor (componentType, name, type, attributes);
132 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
133 public static EventDescriptor CreateEvent (Type componentType,
134 EventDescriptor oldEventDescriptor,
135 params Attribute [] attributes)
137 return new ReflectionEventDescriptor (componentType, oldEventDescriptor, attributes);
140 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
141 public static PropertyDescriptor CreateProperty (Type componentType,
144 params Attribute [] attributes)
146 return new ReflectionPropertyDescriptor (componentType, name, type, attributes);
149 [ReflectionPermission (SecurityAction.LinkDemand, TypeInformation = true, MemberAccess = true)]
150 public static PropertyDescriptor CreateProperty (Type componentType,
151 PropertyDescriptor oldPropertyDescriptor,
152 params Attribute [] attributes)
154 return new ReflectionPropertyDescriptor (componentType, oldPropertyDescriptor, attributes);
157 public static AttributeCollection GetAttributes (Type componentType)
159 if (componentType == null)
160 return AttributeCollection.Empty;
162 return GetTypeInfo (componentType).GetAttributes ();
165 public static AttributeCollection GetAttributes (object component)
167 return GetAttributes (component, false);
171 [EditorBrowsable (EditorBrowsableState.Advanced)]
173 public static AttributeCollection GetAttributes (object component, bool noCustomTypeDesc)
175 if (component == null)
176 return AttributeCollection.Empty;
178 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
179 return ((ICustomTypeDescriptor) component).GetAttributes ();
181 IComponent com = component as IComponent;
182 if (com != null && com.Site != null)
183 return GetComponentInfo (com).GetAttributes ();
185 return GetTypeInfo (component.GetType()).GetAttributes ();
189 public static string GetClassName (object component)
191 return GetClassName (component, false);
195 [EditorBrowsable (EditorBrowsableState.Advanced)]
197 public static string GetClassName (object component, bool noCustomTypeDesc)
199 if (component == null)
200 throw new ArgumentNullException ("component", "component cannot be null");
202 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
203 String res = ((ICustomTypeDescriptor) component).GetClassName ();
205 res = ((ICustomTypeDescriptor) component).GetComponentName ();
207 res = component.GetType ().FullName;
210 return component.GetType ().FullName;
214 public static string GetComponentName (object component)
216 return GetComponentName (component, false);
220 [EditorBrowsable (EditorBrowsableState.Advanced)]
222 public static string GetComponentName (object component, bool noCustomTypeDesc)
224 if (component == null)
225 throw new ArgumentNullException ("component", "component cannot be null");
227 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
228 return ((ICustomTypeDescriptor) component).GetComponentName ();
230 IComponent c = component as IComponent;
231 if (c != null && c.Site != null)
236 return component.GetType().Name;
242 [MonoNotSupported("")]
243 public static string GetFullComponentName (object component)
245 throw new NotImplementedException ();
248 [MonoNotSupported("")]
249 public static string GetClassName (Type componentType)
251 throw new NotImplementedException ();
255 public static TypeConverter GetConverter (object component)
257 return GetConverter (component, false);
261 [EditorBrowsable (EditorBrowsableState.Advanced)]
263 public static TypeConverter GetConverter (object component, bool noCustomTypeDesc)
265 if (component == null)
266 throw new ArgumentNullException ("component", "component cannot be null");
268 if (noCustomTypeDesc == false && component is ICustomTypeDescriptor) {
269 return ((ICustomTypeDescriptor) component).GetConverter ();
273 AttributeCollection atts = GetAttributes (component, false);
274 TypeConverterAttribute tca = (TypeConverterAttribute) atts[typeof(TypeConverterAttribute)];
275 if (tca != null && tca.ConverterTypeName.Length > 0) {
276 t = GetTypeFromName (component as IComponent, tca.ConverterTypeName);
280 ConstructorInfo ci = t.GetConstructor (new Type[] { typeof(Type) });
282 return (TypeConverter) ci.Invoke (new object[] { component.GetType () });
284 return (TypeConverter) Activator.CreateInstance (t);
287 return GetConverter (component.GetType ());
291 private static Hashtable DefaultConverters
294 lock (creatingDefaultConverters) {
295 if (defaultConverters != null)
296 return defaultConverters;
298 defaultConverters = new Hashtable ();
299 defaultConverters.Add (typeof (bool), typeof (BooleanConverter));
300 defaultConverters.Add (typeof (byte), typeof (ByteConverter));
301 defaultConverters.Add (typeof (sbyte), typeof (SByteConverter));
302 defaultConverters.Add (typeof (string), typeof (StringConverter));
303 defaultConverters.Add (typeof (char), typeof (CharConverter));
304 defaultConverters.Add (typeof (short), typeof (Int16Converter));
305 defaultConverters.Add (typeof (int), typeof (Int32Converter));
306 defaultConverters.Add (typeof (long), typeof (Int64Converter));
307 defaultConverters.Add (typeof (ushort), typeof (UInt16Converter));
308 defaultConverters.Add (typeof (uint), typeof (UInt32Converter));
309 defaultConverters.Add (typeof (ulong), typeof (UInt64Converter));
310 defaultConverters.Add (typeof (float), typeof (SingleConverter));
311 defaultConverters.Add (typeof (double), typeof (DoubleConverter));
312 defaultConverters.Add (typeof (decimal), typeof (DecimalConverter));
313 defaultConverters.Add (typeof (object), typeof (TypeConverter));
314 defaultConverters.Add (typeof (void), typeof (TypeConverter));
315 defaultConverters.Add (typeof (Array), typeof (ArrayConverter));
316 defaultConverters.Add (typeof (CultureInfo), typeof (CultureInfoConverter));
317 defaultConverters.Add (typeof (DateTime), typeof (DateTimeConverter));
318 defaultConverters.Add (typeof (Guid), typeof (GuidConverter));
319 defaultConverters.Add (typeof (TimeSpan), typeof (TimeSpanConverter));
320 defaultConverters.Add (typeof (ICollection), typeof (CollectionConverter));
322 return defaultConverters;
326 public static TypeConverter GetConverter (Type type)
328 TypeConverterAttribute tca = null;
330 object [] atts = type.GetCustomAttributes (typeof(TypeConverterAttribute), true);
333 tca = (TypeConverterAttribute)atts[0];
336 t = GetTypeFromName (null, tca.ConverterTypeName);
341 // EnumConverter needs to know the enum type
342 return new EnumConverter(type);
343 } else if (type.IsArray) {
344 return new ArrayConverter ();
349 t = FindConverterType (type);
352 Exception exc = null;
354 return (TypeConverter) Activator.CreateInstance (t);
355 } catch (MissingMethodException e) {
360 return (TypeConverter) Activator.CreateInstance (t, new object [] {type});
361 } catch (MissingMethodException e) {
366 return new ReferenceConverter (type); // Default?
369 private static Type FindConverterType (Type type)
373 // Is there a default converter
374 t = (Type) DefaultConverters [type];
378 // Find default converter with a type this type is assignable to
379 foreach (Type defType in DefaultConverters.Keys) {
380 if (defType.IsInterface && defType.IsAssignableFrom (type)) {
381 return (Type) DefaultConverters [defType];
385 // Nothing found, try the same with our base type
386 if (type.BaseType != null)
387 return FindConverterType (type.BaseType);
392 public static EventDescriptor GetDefaultEvent (Type componentType)
394 return GetTypeInfo (componentType).GetDefaultEvent ();
397 public static EventDescriptor GetDefaultEvent (object component)
399 return GetDefaultEvent (component, false);
403 [EditorBrowsable (EditorBrowsableState.Advanced)]
405 public static EventDescriptor GetDefaultEvent (object component, bool noCustomTypeDesc)
407 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
408 return ((ICustomTypeDescriptor) component).GetDefaultEvent ();
410 IComponent com = component as IComponent;
411 if (com != null && com.Site != null)
412 return GetComponentInfo (com).GetDefaultEvent ();
414 return GetTypeInfo (component.GetType()).GetDefaultEvent ();
418 public static PropertyDescriptor GetDefaultProperty (Type componentType)
420 return GetTypeInfo (componentType).GetDefaultProperty ();
423 public static PropertyDescriptor GetDefaultProperty (object component)
425 return GetDefaultProperty (component, false);
429 [EditorBrowsable (EditorBrowsableState.Advanced)]
431 public static PropertyDescriptor GetDefaultProperty (object component, bool noCustomTypeDesc)
433 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
434 return ((ICustomTypeDescriptor) component).GetDefaultProperty ();
436 IComponent com = component as IComponent;
437 if (com != null && com.Site != null)
438 return GetComponentInfo (com).GetDefaultProperty ();
440 return GetTypeInfo (component.GetType()).GetDefaultProperty ();
444 internal static object CreateEditor (Type t, Type componentType)
449 Exception exc = null;
451 return Activator.CreateInstance (t);
452 } catch (MissingMethodException e) {
457 return Activator.CreateInstance (t, new object [] {componentType});
458 } catch (MissingMethodException e) {
463 private static object FindEditorInTable (Type componentType, Type editorBaseType, Hashtable table)
466 object editor = null;
467 Type ct = componentType;
469 if (componentType == null || editorBaseType == null || table == null)
480 foreach (Type iface in componentType.GetInterfaces ()) {
481 value = table [iface];
490 if (value is string) {
491 editor = CreateEditor (Type.GetType ((string) value), componentType);
492 } else if (value is Type) {
493 editor = CreateEditor ((Type) value, componentType);
494 } else if (value.GetType ().IsSubclassOf (editorBaseType)) {
499 table [componentType] = editor;
504 public static object GetEditor (Type componentType, Type editorBaseType)
507 object [] atts = componentType.GetCustomAttributes (typeof(EditorAttribute), true);
509 if (atts != null && atts.Length != 0) {
510 foreach (EditorAttribute ea in atts)
512 t = GetTypeFromName (null, ea.EditorTypeName);
513 if (t.IsSubclassOf(editorBaseType))
519 return CreateEditor (t, componentType);
523 // Make sure the editorBaseType's static constructor has been called,
524 // since that's where we're putting the initialization of its editor table.
526 System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (editorBaseType.TypeHandle);
528 if (editors != null) {
529 return FindEditorInTable (componentType, editorBaseType, editors [editorBaseType] as Hashtable);
533 return null; // No editor specified
536 public static object GetEditor (object component, Type editorBaseType)
538 return GetEditor (component, editorBaseType, false);
542 [EditorBrowsable (EditorBrowsableState.Advanced)]
544 public static object GetEditor (object component, Type editorBaseType, bool noCustomTypeDesc)
546 if (component == null)
547 throw new ArgumentNullException ("component");
548 if (editorBaseType == null)
549 throw new ArgumentNullException ("editorBaseType");
551 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
552 return ((ICustomTypeDescriptor) component).GetEditor (editorBaseType);
554 object [] atts = component.GetType ().GetCustomAttributes (typeof (EditorAttribute), true);
555 if (atts.Length == 0)
557 string target = editorBaseType.AssemblyQualifiedName;
559 foreach (EditorAttribute ea in atts){
560 if (ea.EditorBaseTypeName == target){
561 Type t = Type.GetType (ea.EditorTypeName, true);
563 return Activator.CreateInstance (t);
569 public static EventDescriptorCollection GetEvents (object component)
571 return GetEvents (component, false);
574 public static EventDescriptorCollection GetEvents (Type componentType)
576 return GetEvents (componentType, null);
579 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes)
581 return GetEvents (component, attributes, false);
585 [EditorBrowsable (EditorBrowsableState.Advanced)]
587 public static EventDescriptorCollection GetEvents (object component, bool noCustomTypeDesc)
589 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
590 return ((ICustomTypeDescriptor) component).GetEvents ();
592 IComponent com = component as IComponent;
593 if (com != null && com.Site != null)
594 return GetComponentInfo (com).GetEvents ();
596 return GetTypeInfo (component.GetType()).GetEvents ();
600 public static EventDescriptorCollection GetEvents (Type componentType, Attribute [] attributes)
602 return GetTypeInfo (componentType).GetEvents (attributes);
606 [EditorBrowsable (EditorBrowsableState.Advanced)]
608 public static EventDescriptorCollection GetEvents (object component, Attribute [] attributes, bool noCustomTypeDesc)
610 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
611 return ((ICustomTypeDescriptor) component).GetEvents (attributes);
613 IComponent com = component as IComponent;
614 if (com != null && com.Site != null)
615 return GetComponentInfo (com).GetEvents (attributes);
617 return GetTypeInfo (component.GetType()).GetEvents (attributes);
621 public static PropertyDescriptorCollection GetProperties (object component)
623 return GetProperties (component, false);
626 public static PropertyDescriptorCollection GetProperties (Type componentType)
628 return GetProperties (componentType, null);
631 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes)
633 return GetProperties (component, attributes, false);
636 public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes, bool noCustomTypeDesc)
638 if (component == null)
639 return PropertyDescriptorCollection.Empty;
641 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
642 return ((ICustomTypeDescriptor) component).GetProperties (attributes);
644 IComponent com = component as IComponent;
645 if (com != null && com.Site != null)
646 return GetComponentInfo (com).GetProperties (attributes);
648 return GetTypeInfo (component.GetType()).GetProperties (attributes);
653 [EditorBrowsable (EditorBrowsableState.Advanced)]
655 public static PropertyDescriptorCollection GetProperties (object component, bool noCustomTypeDesc)
657 if (component == null)
658 return PropertyDescriptorCollection.Empty;
660 if (!noCustomTypeDesc && (component is ICustomTypeDescriptor))
661 return ((ICustomTypeDescriptor) component).GetProperties ();
663 IComponent com = component as IComponent;
664 if (com != null && com.Site != null)
665 return GetComponentInfo (com).GetProperties ();
667 return GetTypeInfo (component.GetType()).GetProperties ();
671 public static PropertyDescriptorCollection GetProperties (Type componentType, Attribute [] attributes)
673 return GetTypeInfo (componentType).GetProperties (attributes);
677 [MonoNotSupported ("")]
678 [EditorBrowsable (EditorBrowsableState.Advanced)]
679 public static TypeDescriptionProvider GetProvider (object instance)
681 throw new NotImplementedException ();
684 [MonoNotSupported ("")]
685 [EditorBrowsable (EditorBrowsableState.Advanced)]
686 public static TypeDescriptionProvider GetProvider (Type type)
688 throw new NotImplementedException ();
691 [MonoNotSupported ("")]
692 [EditorBrowsable (EditorBrowsableState.Advanced)]
693 public static Type GetReflectionType (object instance)
695 throw new NotImplementedException ();
698 [MonoNotSupported ("")]
699 [EditorBrowsable (EditorBrowsableState.Advanced)]
700 public static Type GetReflectionType (Type type)
702 throw new NotImplementedException ();
705 [MonoNotSupported("Associations not supported")]
706 [EditorBrowsable (EditorBrowsableState.Advanced)]
707 public static void CreateAssociation (object primary, object secondary)
709 throw new NotImplementedException ();
712 [MonoNotSupported ("Associations not supported")]
713 [EditorBrowsable (EditorBrowsableState.Advanced)]
714 public static object GetAssociation (Type type, object primary)
716 throw new NotImplementedException ();
719 [MonoNotSupported ("Associations not supported")]
720 [EditorBrowsable (EditorBrowsableState.Advanced)]
721 public static void RemoveAssociation (object primary, object secondary)
723 throw new NotImplementedException ();
726 [MonoNotSupported ("Associations not supported")]
727 [EditorBrowsable (EditorBrowsableState.Advanced)]
728 public static void RemoveAssociations (object primary)
730 throw new NotImplementedException ();
733 [MonoNotSupported ("")]
734 [EditorBrowsable (EditorBrowsableState.Advanced)]
735 public static void RemoveProvider (TypeDescriptionProvider provider, object instance)
737 throw new NotImplementedException ();
740 [MonoNotSupported ("")]
741 [EditorBrowsable (EditorBrowsableState.Advanced)]
742 public static void RemoveProvider (TypeDescriptionProvider provider, Type type)
744 throw new NotImplementedException ();
748 public static void SortDescriptorArray (IList infos)
750 string[] names = new string [infos.Count];
751 object[] values = new object [infos.Count];
752 for (int n=0; n<names.Length; n++) {
753 names[n] = ((MemberDescriptor)infos[n]).Name;
754 values[n] = infos[n];
756 Array.Sort (names, values);
758 foreach (object ob in values)
762 public static IComNativeDescriptorHandler ComNativeDescriptorHandler {
763 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
764 get { return descriptorHandler; }
765 [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
766 set { descriptorHandler = value; }
769 public static void Refresh (Assembly assembly)
771 foreach (Type type in assembly.GetTypes())
775 public static void Refresh (Module module)
777 foreach (Type type in module.GetTypes())
781 public static void Refresh (object component)
783 lock (componentTable)
785 componentTable.Remove (component);
787 if (Refreshed != null) Refreshed (new RefreshEventArgs (component));
790 public static void Refresh (Type type)
794 typeTable.Remove (type);
796 if (Refreshed != null) Refreshed (new RefreshEventArgs (type));
799 static EventHandler onDispose;
801 static void OnComponentDisposed (object sender, EventArgs args)
803 lock (componentTable) {
804 componentTable.Remove (sender);
808 public static event RefreshEventHandler Refreshed;
810 internal static ComponentInfo GetComponentInfo (IComponent com)
812 lock (componentTable)
814 ComponentInfo ci = (ComponentInfo) componentTable [com];
816 if (onDispose == null)
817 onDispose = new EventHandler (OnComponentDisposed);
819 com.Disposed += onDispose;
820 ci = new ComponentInfo (com);
821 componentTable [com] = ci;
827 internal static TypeInfo GetTypeInfo (Type type)
831 TypeInfo ci = (TypeInfo) typeTable [type];
833 ci = new TypeInfo (type);
834 typeTable [type] = ci;
840 internal static Type GetTypeFromName (IComponent component, string typeName)
842 if (component != null && component.Site != null) {
843 ITypeResolutionService resver = (ITypeResolutionService) component.Site.GetService (typeof(ITypeResolutionService));
845 return resver.GetType (typeName, true, false);
848 Type t = Type.GetType (typeName);
849 if (t == null) throw new ArgumentException ("Type '" + typeName + "' not found");
854 internal abstract class Info
857 EventDescriptor _defaultEvent;
858 bool _gotDefaultEvent;
859 PropertyDescriptor _defaultProperty;
860 bool _gotDefaultProperty;
861 AttributeCollection _attributes;
863 public Info (Type infoType)
865 _infoType = infoType;
868 public abstract AttributeCollection GetAttributes ();
869 public abstract EventDescriptorCollection GetEvents ();
870 public abstract PropertyDescriptorCollection GetProperties ();
874 get { return _infoType; }
877 public EventDescriptorCollection GetEvents (Attribute[] attributes)
879 EventDescriptorCollection evs = GetEvents ();
880 if (attributes == null)
883 return evs.Filter (attributes);
886 public PropertyDescriptorCollection GetProperties (Attribute[] attributes)
888 PropertyDescriptorCollection props = GetProperties ();
889 if (attributes == null)
892 return props.Filter (attributes);
895 public EventDescriptor GetDefaultEvent ()
897 if (_gotDefaultEvent)
898 return _defaultEvent;
900 DefaultEventAttribute attr = (DefaultEventAttribute) GetAttributes()[typeof(DefaultEventAttribute)];
901 if (attr == null || attr.Name == null)
902 _defaultEvent = null;
904 EventDescriptorCollection events = GetEvents ();
905 _defaultEvent = events [attr.Name];
907 // In our test case (TypeDescriptorTest.TestGetDefaultEvent), we have
908 // a scenario where a custom filter adds the DefaultEventAttribute,
909 // but its FilterEvents method removes the event the
910 // DefaultEventAttribute applied to. .NET 1.x accepts this and returns
911 // the *other* event defined in the class.
913 // Consequently, we know we have a DefaultEvent, but we need to check
914 // and ensure that the requested event is unfiltered. If it is, just
915 // grab the first element in the collection.
916 if (_defaultEvent == null && events.Count > 0)
917 _defaultEvent = events [0];
920 _gotDefaultEvent = true;
921 return _defaultEvent;
924 public PropertyDescriptor GetDefaultProperty ()
926 if (_gotDefaultProperty)
927 return _defaultProperty;
929 DefaultPropertyAttribute attr = (DefaultPropertyAttribute) GetAttributes()[typeof(DefaultPropertyAttribute)];
930 if (attr == null || attr.Name == null)
931 _defaultProperty = null;
933 PropertyDescriptorCollection properties = GetProperties ();
934 _defaultProperty = properties[attr.Name];
936 _gotDefaultProperty = true;
937 return _defaultProperty;
940 protected AttributeCollection GetAttributes (IComponent comp)
942 if (_attributes != null)
946 object[] ats = _infoType.GetCustomAttributes (true);
947 Hashtable t = new Hashtable ();
949 // Filter the custom attributes, so that only the top
950 // level of the same type are left.
952 for (int i = ats.Length -1; i >= 0; i--) {
953 t [((Attribute) ats[i]).TypeId] = ats[i];
956 if (comp != null && comp.Site != null)
958 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) comp.Site.GetService (typeof(ITypeDescriptorFilterService));
960 cache = filter.FilterAttributes (comp, t);
963 ArrayList atts = new ArrayList ();
964 atts.AddRange (t.Values);
965 AttributeCollection attCol = new AttributeCollection (atts);
967 _attributes = attCol;
972 internal class ComponentInfo : Info
974 IComponent _component;
975 EventDescriptorCollection _events;
976 PropertyDescriptorCollection _properties;
978 public ComponentInfo (IComponent component): base (component.GetType())
980 _component = component;
983 public override AttributeCollection GetAttributes ()
985 return base.GetAttributes (_component);
988 public override EventDescriptorCollection GetEvents ()
994 EventInfo[] events = _component.GetType().GetEvents ();
995 Hashtable t = new Hashtable ();
996 foreach (EventInfo ev in events)
997 t [ev.Name] = new ReflectionEventDescriptor (ev);
999 if (_component.Site != null)
1001 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1003 cache = filter.FilterEvents (_component, t);
1006 ArrayList atts = new ArrayList ();
1007 atts.AddRange (t.Values);
1008 EventDescriptorCollection attCol = new EventDescriptorCollection (atts);
1009 if (cache) _events = attCol;
1013 public override PropertyDescriptorCollection GetProperties ()
1015 if (_properties != null)
1019 PropertyInfo[] props = _component.GetType().GetProperties (BindingFlags.Instance | BindingFlags.Public);
1020 Hashtable t = new Hashtable ();
1021 foreach (PropertyInfo pr in props)
1022 t [pr.Name] = new ReflectionPropertyDescriptor (pr);
1024 if (_component.Site != null)
1026 ITypeDescriptorFilterService filter = (ITypeDescriptorFilterService) _component.Site.GetService (typeof(ITypeDescriptorFilterService));
1028 cache = filter.FilterProperties (_component, t);
1031 PropertyDescriptor[] descriptors = new PropertyDescriptor[t.Values.Count];
1032 t.Values.CopyTo (descriptors, 0);
1033 PropertyDescriptorCollection attCol = new PropertyDescriptorCollection (descriptors, true);
1035 _properties = attCol;
1040 internal class TypeInfo : Info
1042 EventDescriptorCollection _events;
1043 PropertyDescriptorCollection _properties;
1045 public TypeInfo (Type t): base (t)
1049 public override AttributeCollection GetAttributes ()
1051 return base.GetAttributes (null);
1054 public override EventDescriptorCollection GetEvents ()
1056 if (_events != null)
1059 EventInfo[] events = InfoType.GetEvents ();
1060 EventDescriptor[] descs = new EventDescriptor [events.Length];
1061 for (int n=0; n<events.Length; n++)
1062 descs [n] = new ReflectionEventDescriptor (events[n]);
1064 _events = new EventDescriptorCollection (descs);
1068 public override PropertyDescriptorCollection GetProperties ()
1070 if (_properties != null)
1073 PropertyInfo[] props = InfoType.GetProperties (BindingFlags.Instance | BindingFlags.Public);
1074 ArrayList descs = new ArrayList (props.Length);
1075 for (int n=0; n<props.Length; n++)
1076 if (props [n].GetIndexParameters ().Length == 0)
1077 descs.Add (new ReflectionPropertyDescriptor (props[n]));
1079 _properties = new PropertyDescriptorCollection ((PropertyDescriptor[]) descs.ToArray (typeof (PropertyDescriptor)), true);