**** Merged from MCS ****
[mono-project.git] / mcs / class / System / System.ComponentModel / ReflectionPropertyDescriptor.cs
blob78595ac4a3338eb39b23e4f3e75029022ee32fd7
1 //
2 // System.ComponentModel.PropertyDescriptor.cs
3 //
4 // Author:
5 // Lluis Sanchez Gual (lluis@ximian.com)
6 //
7 // (C) Novell, Inc.
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Collections;
33 using System.Reflection;
34 using System.Runtime.InteropServices;
35 using System.ComponentModel.Design;
37 namespace System.ComponentModel
39 internal class ReflectionPropertyDescriptor : PropertyDescriptor
41 PropertyInfo _member;
42 Type _type;
43 Type _componentType;
45 public ReflectionPropertyDescriptor (Type componentType, PropertyDescriptor oldPropertyDescriptor, Attribute [] attributes)
46 : base (oldPropertyDescriptor, attributes)
48 _type = oldPropertyDescriptor.PropertyType;
49 _componentType = componentType;
52 public ReflectionPropertyDescriptor (Type componentType, string name, Type type, Attribute [] attributes)
53 : base (name, attributes)
55 _type = type;
56 _componentType = componentType;
59 public ReflectionPropertyDescriptor (PropertyInfo info)
60 : base (info.Name, (Attribute[])info.GetCustomAttributes (true))
62 _member = info;
63 _componentType = _member.DeclaringType;
66 PropertyInfo GetPropertyInfo ()
68 if (_member == null) {
69 _member = _componentType.GetProperty (Name);
70 if (_member == null)
71 throw new ArgumentException ("Accessor methods for the " + Name + " property are missing");
73 return _member;
76 public override Type ComponentType
78 get { return _componentType; }
81 public override bool IsReadOnly
83 get
85 return !GetPropertyInfo ().CanWrite;
89 public override Type PropertyType
91 get
93 return GetPropertyInfo ().PropertyType;
97 public override object GetValue (object component)
99 return GetPropertyInfo ().GetValue (component, null);
102 DesignerTransaction CreateTransaction (object obj)
104 Component com = obj as Component;
105 if (com == null || com.Site == null) return null;
107 IDesignerHost dh = (IDesignerHost) com.Site.GetService (typeof(IDesignerHost));
108 if (dh == null) return null;
110 DesignerTransaction tran = dh.CreateTransaction ();
111 IComponentChangeService ccs = (IComponentChangeService) com.Site.GetService (typeof(IComponentChangeService));
112 if (ccs != null)
113 ccs.OnComponentChanging (com, this);
114 return tran;
117 void EndTransaction (object obj, DesignerTransaction tran, object oldValue, object newValue, bool commit)
119 if (tran == null) return;
121 if (commit) {
122 Component com = obj as Component;
123 IComponentChangeService ccs = (IComponentChangeService) com.Site.GetService (typeof(IComponentChangeService));
124 if (ccs != null)
125 ccs.OnComponentChanged (com, this, oldValue, newValue);
126 tran.Commit ();
128 else
129 tran.Cancel ();
132 public override void SetValue (object component, object value)
134 DesignerTransaction tran = CreateTransaction (component);
135 object old = GetValue (component);
139 GetPropertyInfo ().SetValue (component, value, null);
140 EndTransaction (component, tran, old, value, true);
142 catch
144 EndTransaction (component, tran, old, value, false);
145 throw;
149 public override void ResetValue (object component)
151 DefaultValueAttribute attrib = ((DefaultValueAttribute) Attributes[typeof (DefaultValueAttribute)]);
152 if (attrib != null) {
153 SetValue (component, attrib.Value);
156 DesignerTransaction tran = CreateTransaction (component);
157 object old = GetValue (component);
161 MethodInfo mi = component.GetType().GetMethod ("Reset" + Name, Type.EmptyTypes);
162 if (mi != null) mi.Invoke (component, null);
163 EndTransaction (component, tran, old, GetValue (component), true);
165 catch
167 EndTransaction (component, tran, old, GetValue (component), false);
168 throw;
172 public override bool CanResetValue (object component)
174 DefaultValueAttribute attrib = ((DefaultValueAttribute) Attributes[typeof (DefaultValueAttribute)]);
175 if (attrib != null) {
176 object current = GetValue (component);
177 if ((attrib.Value == null || current == null) && attrib.Value != current) return true;
178 return !attrib.Value.Equals (current);
180 else {
181 MethodInfo mi = component.GetType().GetMethod ("ShouldPersist" + Name, Type.EmptyTypes);
182 if (mi != null) return (bool) mi.Invoke (component, null);
183 mi = component.GetType().GetMethod ("Reset" + Name, Type.EmptyTypes);
184 return (mi != null);
188 public override bool ShouldSerializeValue (object component)
190 DefaultValueAttribute attrib = ((DefaultValueAttribute) Attributes[typeof (DefaultValueAttribute)]);
191 if (attrib != null) {
192 object current = GetValue (component);
193 if ((attrib.Value == null || current == null) && attrib.Value != current) return true;
194 return !attrib.Value.Equals (current);
196 else {
197 MethodInfo mi = component.GetType().GetMethod ("ShouldSerialize" + Name, Type.EmptyTypes);
198 if (mi != null) return (bool) mi.Invoke (component, null);
199 return true;