2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System / System.ComponentModel / PropertyDescriptor.cs
blob74940e0787d9f660fcbd8a582e76ef16e121d14c
1 //
2 // System.ComponentModel.PropertyDescriptor.cs
3 //
4 // Author:
5 // Miguel de Icaza (miguel@ximian.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 // Ivan N. Zlatev (contact@i-nz.net)
8 //
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:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
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.
35 using System;
36 using System.Collections;
37 using System.Reflection;
38 using System.Runtime.InteropServices;
40 namespace System.ComponentModel
42 #if MOONLIGHT
43 public abstract class PropertyDescriptor
46 #else
47 [ComVisible (true)]
48 public abstract class PropertyDescriptor : MemberDescriptor
50 TypeConverter converter;
52 protected PropertyDescriptor (MemberDescriptor reference)
53 : base (reference)
57 protected PropertyDescriptor (MemberDescriptor reference, Attribute [] attrs)
58 : base (reference, attrs)
62 protected PropertyDescriptor (string name, Attribute [] attrs)
63 : base (name, attrs)
67 public abstract Type ComponentType { get; }
69 public virtual TypeConverter Converter {
70 get {
71 if (converter == null && PropertyType != null) {
72 TypeConverterAttribute at = (TypeConverterAttribute) Attributes [typeof(TypeConverterAttribute)];
73 if (at != null && at != TypeConverterAttribute.Default) {
74 Type converterType = GetTypeFromName (at.ConverterTypeName);
75 if (converterType != null && typeof (TypeConverter).IsAssignableFrom (converterType))
76 converter = (TypeConverter)CreateInstance (converterType);
78 if (converter == null)
79 converter = TypeDescriptor.GetConverter (PropertyType);
81 return converter;
85 public virtual bool IsLocalizable {
86 get {
87 foreach (Attribute attr in AttributeArray){
88 if (attr is LocalizableAttribute)
89 return ((LocalizableAttribute) attr).IsLocalizable;
92 return false;
96 public abstract bool IsReadOnly { get; }
98 public abstract Type PropertyType { get; }
100 #if NET_2_0
101 public virtual bool SupportsChangeEvents {
102 get { return false; }
104 #endif
106 public DesignerSerializationVisibility SerializationVisibility {
107 get {
108 foreach (Attribute attr in AttributeArray) {
109 if (attr is DesignerSerializationVisibilityAttribute){
110 DesignerSerializationVisibilityAttribute a;
112 a = (DesignerSerializationVisibilityAttribute) attr;
114 return a.Visibility;
118 return DesignerSerializationVisibility.Visible;
122 Hashtable notifiers;
124 public virtual void AddValueChanged (object component, EventHandler handler)
126 EventHandler component_notifiers;
128 if (component == null)
129 throw new ArgumentNullException ("component");
131 if (handler == null)
132 throw new ArgumentNullException ("handler");
134 if (notifiers == null)
135 notifiers = new Hashtable ();
137 component_notifiers = (EventHandler) notifiers [component];
139 if (component_notifiers != null) {
140 component_notifiers += handler;
141 notifiers [component] = component_notifiers;
142 } else {
143 notifiers [component] = handler;
147 public virtual void RemoveValueChanged (object component, System.EventHandler handler)
149 EventHandler component_notifiers;
151 if (component == null)
152 throw new ArgumentNullException ("component");
154 if (handler == null)
155 throw new ArgumentNullException ("handler");
157 if (notifiers == null) return;
159 component_notifiers = (EventHandler) notifiers [component];
160 component_notifiers -= handler;
162 if (component_notifiers == null)
163 notifiers.Remove (component);
164 else
165 notifiers [component] = component_notifiers;
168 #if NET_2_0
169 protected override void FillAttributes (IList attributeList)
171 base.FillAttributes (attributeList);
174 protected override object GetInvocationTarget (Type type, object instance)
176 if (type == null)
177 throw new ArgumentNullException ("type");
178 if (instance == null)
179 throw new ArgumentNullException ("instance");
181 if (instance is CustomTypeDescriptor) {
182 CustomTypeDescriptor ctd = (CustomTypeDescriptor) instance;
183 return ctd.GetPropertyOwner (this);
186 return base.GetInvocationTarget (type, instance);
189 protected internal EventHandler GetValueChangedHandler (object component)
191 if (component == null || notifiers == null)
192 return null;
194 return (EventHandler) notifiers [component];
196 #endif
198 protected virtual void OnValueChanged (object component, EventArgs e)
200 if (notifiers == null)
201 return;
203 EventHandler component_notifiers = (EventHandler) notifiers [component];
205 if (component_notifiers == null)
206 return;
208 component_notifiers (component, e);
211 public abstract object GetValue (object component);
213 public abstract void SetValue (object component, object value);
215 public abstract void ResetValue (object component);
217 public abstract bool CanResetValue (object component);
219 public abstract bool ShouldSerializeValue (object component);
221 protected object CreateInstance (Type type)
223 if (type == null || PropertyType == null)
224 return null;
226 object instance = null;
227 Type[] paramTypes = new Type[] { typeof (Type) };
228 ConstructorInfo ctor = type.GetConstructor (paramTypes);
229 if (ctor != null) {
230 object[] parameters = new object[] { PropertyType };
231 #if NET_2_0
232 instance = TypeDescriptor.CreateInstance (null, type, paramTypes, parameters);
233 #else
234 instance = ctor.Invoke (parameters);
235 #endif
236 } else {
237 #if NET_2_0
238 instance = TypeDescriptor.CreateInstance (null, type, null, null);
239 #else
240 instance = Activator.CreateInstance (type);
241 #endif
243 return instance;
246 public override bool Equals(object obj)
248 if (!base.Equals (obj)) return false;
249 PropertyDescriptor other = obj as PropertyDescriptor;
250 if (other == null) return false;
251 return other.PropertyType == PropertyType;
254 public PropertyDescriptorCollection GetChildProperties()
256 return GetChildProperties (null, null);
259 public PropertyDescriptorCollection GetChildProperties(object instance)
261 return GetChildProperties (instance, null);
264 public PropertyDescriptorCollection GetChildProperties(Attribute[] filter)
266 return GetChildProperties (null, filter);
269 public override int GetHashCode()
271 return base.GetHashCode ();
274 public virtual PropertyDescriptorCollection GetChildProperties (object instance, Attribute[] filter)
276 return TypeDescriptor.GetProperties (instance, filter);
279 public virtual object GetEditor (Type editorBaseType)
281 Type t = null;
282 Attribute [] atts = AttributeArray;
284 if (atts != null && atts.Length != 0) {
285 foreach (Attribute a in atts) {
286 EditorAttribute ea = a as EditorAttribute;
288 if (ea == null)
289 continue;
291 t = GetTypeFromName (ea.EditorTypeName);
292 if (t != null && t.IsSubclassOf(editorBaseType))
293 break;
297 object editor = null;
298 if (t != null)
299 editor = CreateInstance (t);
300 if (editor == null)
301 editor = TypeDescriptor.GetEditor (PropertyType, editorBaseType);
302 return editor;
305 protected Type GetTypeFromName (string typeName)
307 if (typeName == null || ComponentType == null || typeName.Trim ().Length == 0)
308 return null;
310 Type type = Type.GetType (typeName);
311 if (type == null) {
312 // Try to strip the type typeName only
313 int index = typeName.IndexOf (",");
314 if (index != -1)
315 typeName = typeName.Substring (0, index);
316 type = ComponentType.Assembly.GetType (typeName);
318 return type;
321 #endif