Mercurial > pub > bltoolkit
comparison Source/EditableObjects/EditableObject.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 using System; | |
2 using System.Collections; | |
3 using System.ComponentModel; | |
4 using System.Data.SqlTypes; | |
5 using System.Reflection; | |
6 using System.Runtime.InteropServices; | |
7 using System.Xml; | |
8 using System.Xml.Serialization; | |
9 | |
10 using BLToolkit.Common; | |
11 using BLToolkit.ComponentModel; | |
12 using BLToolkit.Mapping; | |
13 using BLToolkit.Reflection; | |
14 using BLToolkit.TypeBuilder; | |
15 using BLToolkit.Validation; | |
16 | |
17 namespace BLToolkit.EditableObjects | |
18 { | |
19 #region Instance Types | |
20 [GlobalInstanceType(typeof(byte), typeof(EditableValue<byte>))] | |
21 [GlobalInstanceType(typeof(char), typeof(EditableValue<char>))] | |
22 [GlobalInstanceType(typeof(ushort), typeof(EditableValue<ushort>))] | |
23 [GlobalInstanceType(typeof(uint), typeof(EditableValue<uint>))] | |
24 [GlobalInstanceType(typeof(ulong), typeof(EditableValue<ulong>))] | |
25 [GlobalInstanceType(typeof(bool), typeof(EditableValue<bool>))] | |
26 [GlobalInstanceType(typeof(sbyte), typeof(EditableValue<sbyte>))] | |
27 [GlobalInstanceType(typeof(short), typeof(EditableValue<short>))] | |
28 [GlobalInstanceType(typeof(int), typeof(EditableValue<int>))] | |
29 [GlobalInstanceType(typeof(long), typeof(EditableValue<long>))] | |
30 [GlobalInstanceType(typeof(float), typeof(EditableValue<float>))] | |
31 [GlobalInstanceType(typeof(double), typeof(EditableValue<double>))] | |
32 [GlobalInstanceType(typeof(string), typeof(EditableValue<string>), "")] | |
33 [GlobalInstanceType(typeof(DateTime), typeof(EditableValue<DateTime>))] | |
34 [GlobalInstanceType(typeof(decimal), typeof(EditableValue<decimal>))] | |
35 [GlobalInstanceType(typeof(Guid), typeof(EditableValue<Guid>))] | |
36 | |
37 [GlobalInstanceType(typeof(byte?), typeof(EditableValue<byte?>))] | |
38 [GlobalInstanceType(typeof(char?), typeof(EditableValue<char?>))] | |
39 [GlobalInstanceType(typeof(ushort?), typeof(EditableValue<ushort?>))] | |
40 [GlobalInstanceType(typeof(uint?), typeof(EditableValue<uint?>))] | |
41 [GlobalInstanceType(typeof(ulong?), typeof(EditableValue<ulong?>))] | |
42 [GlobalInstanceType(typeof(bool?), typeof(EditableValue<bool?>))] | |
43 [GlobalInstanceType(typeof(sbyte?), typeof(EditableValue<sbyte?>))] | |
44 [GlobalInstanceType(typeof(short?), typeof(EditableValue<short?>))] | |
45 [GlobalInstanceType(typeof(int?), typeof(EditableValue<int?>))] | |
46 [GlobalInstanceType(typeof(long?), typeof(EditableValue<long?>))] | |
47 [GlobalInstanceType(typeof(float?), typeof(EditableValue<float?>))] | |
48 [GlobalInstanceType(typeof(double?), typeof(EditableValue<double?>))] | |
49 [GlobalInstanceType(typeof(DateTime?), typeof(EditableValue<DateTime?>))] | |
50 [GlobalInstanceType(typeof(decimal?), typeof(EditableValue<decimal?>))] | |
51 [GlobalInstanceType(typeof(Guid?), typeof(EditableValue<Guid?>))] | |
52 | |
53 [GlobalInstanceType(typeof(SqlBoolean), typeof(EditableValue<SqlBoolean>))] | |
54 [GlobalInstanceType(typeof(SqlByte), typeof(EditableValue<SqlByte>))] | |
55 [GlobalInstanceType(typeof(SqlDateTime), typeof(EditableValue<SqlDateTime>))] | |
56 [GlobalInstanceType(typeof(SqlDecimal), typeof(EditableValue<SqlDecimal>))] | |
57 [GlobalInstanceType(typeof(SqlDouble), typeof(EditableValue<SqlDouble>))] | |
58 [GlobalInstanceType(typeof(SqlGuid), typeof(EditableValue<SqlGuid>))] | |
59 [GlobalInstanceType(typeof(SqlInt16), typeof(EditableValue<SqlInt16>))] | |
60 [GlobalInstanceType(typeof(SqlInt32), typeof(EditableValue<SqlInt32>))] | |
61 [GlobalInstanceType(typeof(SqlInt64), typeof(EditableValue<SqlInt64>))] | |
62 [GlobalInstanceType(typeof(SqlMoney), typeof(EditableValue<SqlMoney>))] | |
63 [GlobalInstanceType(typeof(SqlSingle), typeof(EditableValue<SqlSingle>))] | |
64 [GlobalInstanceType(typeof(SqlString), typeof(EditableValue<SqlString>), "")] | |
65 | |
66 [GlobalInstanceType(typeof(XmlDocument), typeof(EditableXmlDocument))] | |
67 [GlobalInstanceType(typeof(EditableObject), typeof(EditableObjectHolder), IsObjectHolder=true)] | |
68 #endregion | |
69 [ImplementInterface(typeof(IEditable))] | |
70 [ImplementInterface(typeof(IMemberwiseEditable))] | |
71 [ImplementInterface(typeof(IPrintDebugState))] | |
72 [ImplementInterface(typeof(ISetParent))] | |
73 [ComVisible(true)] | |
74 [Serializable] | |
75 public abstract class EditableObject : EntityBase, | |
76 ICloneable, IEditableObject, INotifyPropertyChanged, | |
77 ISupportMapping, IValidatable, IPropertyChanged, INotifyObjectEdit | |
78 { | |
79 #region Constructor | |
80 | |
81 protected EditableObject() | |
82 { | |
83 ISetParent setParent = this as ISetParent; | |
84 | |
85 if (setParent != null) | |
86 setParent.SetParent(this, null); | |
87 } | |
88 | |
89 #endregion | |
90 | |
91 #region IEditable | |
92 | |
93 public virtual void AcceptChanges() | |
94 { | |
95 if (this is IEditable) | |
96 ((IEditable)this).AcceptChanges(); | |
97 } | |
98 | |
99 public virtual void RejectChanges() | |
100 { | |
101 var dirtyMembers = GetDirtyMembers(); | |
102 | |
103 if (this is IEditable) | |
104 ((IEditable)this).RejectChanges(); | |
105 | |
106 foreach (PropertyInfo dirtyMember in dirtyMembers) | |
107 OnPropertyChanged(dirtyMember.Name); | |
108 } | |
109 | |
110 [MapIgnore, Bindable(false)] | |
111 public virtual bool IsDirty | |
112 { | |
113 get { return this is IEditable? ((IEditable)this).IsDirty: false; } | |
114 } | |
115 | |
116 public virtual void AcceptMemberChanges(string memberName) | |
117 { | |
118 if (this is IMemberwiseEditable) | |
119 ((IMemberwiseEditable)this).AcceptMemberChanges(null, memberName); | |
120 } | |
121 | |
122 public virtual void RejectMemberChanges(string memberName) | |
123 { | |
124 bool notifyChange = IsDirtyMember(memberName); | |
125 | |
126 if (this is IMemberwiseEditable) | |
127 ((IMemberwiseEditable)this).RejectMemberChanges(null, memberName); | |
128 | |
129 if (notifyChange) | |
130 OnPropertyChanged(memberName); | |
131 } | |
132 | |
133 public virtual bool IsDirtyMember(string memberName) | |
134 { | |
135 bool isDirty = false; | |
136 | |
137 if (this is IMemberwiseEditable) | |
138 ((IMemberwiseEditable)this).IsDirtyMember(null, memberName, ref isDirty); | |
139 | |
140 return isDirty; | |
141 } | |
142 | |
143 public virtual PropertyInfo[] GetDirtyMembers() | |
144 { | |
145 ArrayList list = new ArrayList(); | |
146 | |
147 if (this is IMemberwiseEditable) | |
148 ((IMemberwiseEditable)this).GetDirtyMembers(null, list); | |
149 | |
150 return (PropertyInfo[])list.ToArray(typeof(PropertyInfo)); | |
151 } | |
152 | |
153 [MapIgnore, Bindable(false)] | |
154 public virtual string PrintDebugState | |
155 { | |
156 get | |
157 { | |
158 #if DEBUG | |
159 if (this is IPrintDebugState) | |
160 { | |
161 string s = string.Format( | |
162 "====== {0} ======\r\nIsDirty: {1}\r\n" + | |
163 "Property IsDirty Original Current\r\n" + | |
164 "==================== = ======================================== ========================================\r\n", | |
165 GetType().Name, IsDirty); | |
166 | |
167 ((IPrintDebugState)this).PrintDebugState(null, ref s); | |
168 | |
169 return s + "\r\n"; | |
170 } | |
171 #endif | |
172 return ""; | |
173 } | |
174 } | |
175 | |
176 #endregion | |
177 | |
178 #region ISupportMapping Members | |
179 | |
180 private bool _isInMapping; | |
181 [MapIgnore, Bindable(false)] | |
182 public bool IsInMapping | |
183 { | |
184 get { return _isInMapping; } | |
185 } | |
186 | |
187 protected void SetIsInMapping(bool isInMapping) | |
188 { | |
189 _isInMapping = isInMapping; | |
190 } | |
191 | |
192 public virtual void BeginMapping(InitContext initContext) | |
193 { | |
194 _isInMapping = true; | |
195 } | |
196 | |
197 public virtual void EndMapping(InitContext initContext) | |
198 { | |
199 if (initContext.IsDestination) | |
200 AcceptChanges(); | |
201 | |
202 _isInMapping = false; | |
203 | |
204 if (initContext.IsDestination) | |
205 OnPropertyChanged(""); | |
206 } | |
207 | |
208 #endregion | |
209 | |
210 #region Notify Changes | |
211 | |
212 protected internal virtual void OnPropertyChanged(string propertyName) | |
213 { | |
214 if (NotifyChanges && PropertyChanged != null) | |
215 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); | |
216 } | |
217 | |
218 private int _notNotifyChangesCount = 0; | |
219 [MapIgnore, Bindable(false), XmlIgnore] | |
220 public bool NotifyChanges | |
221 { | |
222 get { return _notNotifyChangesCount == 0; } | |
223 set { _notNotifyChangesCount = value? 0: 1; } | |
224 } | |
225 | |
226 public void LockNotifyChanges() | |
227 { | |
228 _notNotifyChangesCount++; | |
229 } | |
230 | |
231 public void UnlockNotifyChanges() | |
232 { | |
233 _notNotifyChangesCount--; | |
234 | |
235 if (_notNotifyChangesCount < 0) | |
236 throw new InvalidOperationException(); | |
237 } | |
238 | |
239 #endregion | |
240 | |
241 #region IPropertyChanged Members | |
242 | |
243 void IPropertyChanged.OnPropertyChanged(PropertyInfo propertyInfo) | |
244 { | |
245 if (_isInMapping == false) | |
246 OnPropertyChanged(propertyInfo.Name); | |
247 } | |
248 | |
249 #endregion | |
250 | |
251 #region INotifyPropertyChanged Members | |
252 | |
253 [field : NonSerialized] | |
254 public virtual event PropertyChangedEventHandler PropertyChanged; | |
255 | |
256 #endregion | |
257 | |
258 #region IEditableObject Members | |
259 | |
260 public virtual void BeginEdit() | |
261 { | |
262 if (ObjectEdit != null) | |
263 ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Begin)); | |
264 } | |
265 | |
266 public virtual void CancelEdit() | |
267 { | |
268 if (ObjectEdit != null) | |
269 ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Cancel)); | |
270 } | |
271 | |
272 public virtual void EndEdit() | |
273 { | |
274 if (ObjectEdit != null) | |
275 ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.End)); | |
276 } | |
277 | |
278 #endregion | |
279 | |
280 #region INotifyObjectEdit Members | |
281 | |
282 public event ObjectEditEventHandler ObjectEdit; | |
283 | |
284 #endregion | |
285 | |
286 #region ICloneable Members | |
287 | |
288 ///<summary> | |
289 ///Creates a new object that is a copy of the current instance. | |
290 ///</summary> | |
291 ///<returns> | |
292 ///A new object that is a copy of this instance. | |
293 ///</returns> | |
294 object ICloneable.Clone() | |
295 { | |
296 return TypeAccessor.Copy(this); | |
297 } | |
298 | |
299 #endregion | |
300 } | |
301 } |