2 // System.ComponentModel.PropertyDescriptor.cs
5 // Miguel de Icaza (miguel@ximian.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // Ivan N. Zlatev (contact@i-nz.net)
9 // (C) Ximian, Inc. http://www.ximian.com
10 // (C) 2003 Andreas Nahr
11 // (C) 2008 Novell, Inc. http://www.novell.com
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Reflection;
38 using System.Runtime.InteropServices;
40 namespace System.ComponentModel
43 public abstract class PropertyDescriptor : MemberDescriptor
45 TypeConverter converter;
47 protected PropertyDescriptor (MemberDescriptor reference)
52 protected PropertyDescriptor (MemberDescriptor reference, Attribute [] attrs)
53 : base (reference, attrs)
57 protected PropertyDescriptor (string name, Attribute [] attrs)
62 public abstract Type ComponentType { get; }
64 public virtual TypeConverter Converter {
66 if (converter == null && PropertyType != null) {
67 TypeConverterAttribute at = (TypeConverterAttribute) Attributes [typeof(TypeConverterAttribute)];
68 if (at != null && at != TypeConverterAttribute.Default) {
69 Type converterType = GetTypeFromName (at.ConverterTypeName);
70 if (converterType != null && typeof (TypeConverter).IsAssignableFrom (converterType))
71 converter = (TypeConverter)CreateInstance (converterType);
73 if (converter == null)
74 converter = TypeDescriptor.GetConverter (PropertyType);
80 public virtual bool IsLocalizable {
82 foreach (Attribute attr in AttributeArray){
83 if (attr is LocalizableAttribute)
84 return ((LocalizableAttribute) attr).IsLocalizable;
91 public abstract bool IsReadOnly { get; }
93 public abstract Type PropertyType { get; }
95 public virtual bool SupportsChangeEvents {
99 public DesignerSerializationVisibility SerializationVisibility {
101 foreach (Attribute attr in AttributeArray) {
102 if (attr is DesignerSerializationVisibilityAttribute){
103 DesignerSerializationVisibilityAttribute a;
105 a = (DesignerSerializationVisibilityAttribute) attr;
111 return DesignerSerializationVisibility.Visible;
117 public virtual void AddValueChanged (object component, EventHandler handler)
119 EventHandler component_notifiers;
121 if (component == null)
122 throw new ArgumentNullException ("component");
125 throw new ArgumentNullException ("handler");
127 if (notifiers == null)
128 notifiers = new Hashtable ();
130 component_notifiers = (EventHandler) notifiers [component];
132 if (component_notifiers != null) {
133 component_notifiers += handler;
134 notifiers [component] = component_notifiers;
136 notifiers [component] = handler;
140 public virtual void RemoveValueChanged (object component, System.EventHandler handler)
142 EventHandler component_notifiers;
144 if (component == null)
145 throw new ArgumentNullException ("component");
148 throw new ArgumentNullException ("handler");
150 if (notifiers == null) return;
152 component_notifiers = (EventHandler) notifiers [component];
153 component_notifiers -= handler;
155 if (component_notifiers == null)
156 notifiers.Remove (component);
158 notifiers [component] = component_notifiers;
161 protected override void FillAttributes (IList attributeList)
163 base.FillAttributes (attributeList);
166 protected override object GetInvocationTarget (Type type, object instance)
169 throw new ArgumentNullException ("type");
170 if (instance == null)
171 throw new ArgumentNullException ("instance");
173 if (instance is CustomTypeDescriptor) {
174 CustomTypeDescriptor ctd = (CustomTypeDescriptor) instance;
175 return ctd.GetPropertyOwner (this);
178 return base.GetInvocationTarget (type, instance);
181 protected internal EventHandler GetValueChangedHandler (object component)
183 if (component == null || notifiers == null)
186 return (EventHandler) notifiers [component];
189 protected virtual void OnValueChanged (object component, EventArgs e)
191 if (notifiers == null)
194 EventHandler component_notifiers = (EventHandler) notifiers [component];
196 if (component_notifiers == null)
199 component_notifiers (component, e);
202 public abstract object GetValue (object component);
204 public abstract void SetValue (object component, object value);
206 public abstract void ResetValue (object component);
208 public abstract bool CanResetValue (object component);
210 public abstract bool ShouldSerializeValue (object component);
212 protected object CreateInstance (Type type)
214 if (type == null || PropertyType == null)
217 object instance = null;
218 Type[] paramTypes = new Type[] { typeof (Type) };
219 ConstructorInfo ctor = type.GetConstructor (paramTypes);
221 object[] parameters = new object[] { PropertyType };
222 instance = TypeDescriptor.CreateInstance (null, type, paramTypes, parameters);
224 instance = TypeDescriptor.CreateInstance (null, type, null, null);
229 public override bool Equals(object obj)
231 if (!base.Equals (obj)) return false;
232 PropertyDescriptor other = obj as PropertyDescriptor;
233 if (other == null) return false;
234 return other.PropertyType == PropertyType;
237 public PropertyDescriptorCollection GetChildProperties()
239 return GetChildProperties (null, null);
242 public PropertyDescriptorCollection GetChildProperties(object instance)
244 return GetChildProperties (instance, null);
247 public PropertyDescriptorCollection GetChildProperties(Attribute[] filter)
249 return GetChildProperties (null, filter);
252 public override int GetHashCode()
254 return base.GetHashCode ();
257 public virtual PropertyDescriptorCollection GetChildProperties (object instance, Attribute[] filter)
259 return TypeDescriptor.GetProperties (instance, filter);
262 public virtual object GetEditor (Type editorBaseType)
265 Attribute [] atts = AttributeArray;
267 if (atts != null && atts.Length != 0) {
268 foreach (Attribute a in atts) {
269 EditorAttribute ea = a as EditorAttribute;
274 t = GetTypeFromName (ea.EditorTypeName);
275 if (t != null && t.IsSubclassOf(editorBaseType))
280 object editor = null;
282 editor = CreateInstance (t);
284 editor = TypeDescriptor.GetEditor (PropertyType, editorBaseType);
288 protected Type GetTypeFromName (string typeName)
290 if (typeName == null || ComponentType == null || typeName.Trim ().Length == 0)
293 Type type = Type.GetType (typeName);
295 // Try to strip the type typeName only
296 int index = typeName.IndexOf (",");
298 typeName = typeName.Substring (0, index);
299 type = ComponentType.Assembly.GetType (typeName);