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 }