9using System.Collections.Generic;
10using System.Reflection;
12using System.ComponentModel;
31 private Stack<byte[]> _stateStack =
new Stack<byte[]>();
33 private bool _bindingEdit;
48 [EditorBrowsable(EditorBrowsableState.Never)]
63 get {
return EditLevel; }
69 [EditorBrowsable(EditorBrowsableState.Never)]
70 protected int EditLevel
72 get {
return _stateStack.Count; }
77 if (!parentBindingEdit)
78 CopyState(parentEditLevel);
81 void IUndoableObject.UndoChanges(
int parentEditLevel,
bool parentBindingEdit)
83 if (!parentBindingEdit)
84 UndoChanges(parentEditLevel);
87 void IUndoableObject.AcceptChanges(
int parentEditLevel,
bool parentBindingEdit)
89 if (!parentBindingEdit)
90 AcceptChanges(parentEditLevel);
97 [EditorBrowsable(EditorBrowsableState.Advanced)]
106 [EditorBrowsable(EditorBrowsableState.Advanced)]
115 [EditorBrowsable(EditorBrowsableState.Never)]
116 protected internal void CopyState(
int parentEditLevel)
120 Type currentType = this.GetType();
123 if (this.EditLevel + 1 > parentEditLevel)
128 var currentTypeName = currentType.FullName;
130 List<DynamicMemberHandle> handlers =
131 UndoableHandler.GetCachedFieldHandlers(currentType);
132 foreach (var h
in handlers)
134 var value = h.DynamicMemberGet(
this);
135 var fieldName = GetFieldName(currentTypeName, h.MemberName);
142 state.Add(fieldName,
null);
147 ((IUndoableObject)value).CopyState(this.EditLevel + 1,
BindingEdit);
153 using (MemoryStream buffer =
new MemoryStream())
155 var formatter = SerializationFormatterFactory.GetFormatter();
156 formatter.Serialize(buffer, value);
157 state.Add(fieldName, buffer.ToArray());
163 state.Add(fieldName, value);
167 currentType = currentType.BaseType;
171 using (MemoryStream buffer =
new MemoryStream())
173 var formatter = SerializationFormatterFactory.GetFormatter();
174 formatter.Serialize(buffer, state);
175 _stateStack.Push(buffer.ToArray());
184 [EditorBrowsable(EditorBrowsableState.Advanced)]
193 [EditorBrowsable(EditorBrowsableState.Advanced)]
208 [EditorBrowsable(EditorBrowsableState.Never)]
209 protected internal void UndoChanges(
int parentEditLevel)
218 if (this.EditLevel - 1 != parentEditLevel)
222 using (MemoryStream buffer =
new MemoryStream(_stateStack.Pop()))
225 var formatter = SerializationFormatterFactory.GetFormatter();
229 Type currentType = this.GetType();
233 var currentTypeName = currentType.FullName;
236 List<DynamicMemberHandle> handlers = UndoableHandler.GetCachedFieldHandlers(currentType);
237 foreach (var h
in handlers)
240 var value = h.DynamicMemberGet(
this);
241 var fieldName = GetFieldName(currentTypeName, h.MemberName);
243 if (typeof(IUndoableObject).IsAssignableFrom(h.MemberType))
251 h.DynamicMemberSet(
this,
null);
259 ((IUndoableObject)value).UndoChanges(this.EditLevel,
BindingEdit);
266 using (MemoryStream buffer =
new MemoryStream((
byte[])state[fieldName]))
269 var formatter = SerializationFormatterFactory.GetFormatter();
270 var obj = formatter.Deserialize(buffer);
271 h.DynamicMemberSet(
this, obj);
277 h.DynamicMemberSet(
this, state[fieldName]);
281 currentType = currentType.BaseType;
291 [EditorBrowsable(EditorBrowsableState.Advanced)]
300 [EditorBrowsable(EditorBrowsableState.Advanced)]
314 [EditorBrowsable(EditorBrowsableState.Never)]
315 protected internal void AcceptChanges(
int parentEditLevel)
319 if (this.EditLevel - 1 != parentEditLevel)
325 Type currentType = this.GetType();
330 List<DynamicMemberHandle> handlers = UndoableHandler.GetCachedFieldHandlers(currentType);
331 foreach (var h
in handlers)
336 object value = h.DynamicMemberGet(
this);
341 ((Core.IUndoableObject)value).AcceptChanges(this.EditLevel,
BindingEdit);
346 currentType = currentType.BaseType;
358 private static string GetFieldName(
string typeName,
string memberName)
360 return typeName +
"." + memberName;
364 #region Helper Functions
366 private static bool NotUndoableField(FieldInfo field)
368 return Attribute.IsDefined(field, typeof(NotUndoableAttribute));
371 private static string GetFieldName(FieldInfo field)
373 return field.DeclaringType.FullName +
"!" + field.Name;
378 #region Reset child edit level
380 internal static void ResetChildEditLevel(IUndoableObject child,
int parentEditLevel,
bool bindingEdit)
382 int targetLevel = parentEditLevel;
383 if (bindingEdit && targetLevel > 0 && !(child is FieldManager.FieldDataManager))
387 while (child.EditLevel > targetLevel)
388 child.AcceptChanges(targetLevel,
false);
391 while (child.EditLevel < targetLevel)
392 child.CopyState(targetLevel,
false);
397 #region MobileObject overrides
413 info.
AddValue(
"_bindingEdit", _bindingEdit);
414 if (_stateStack.Count > 0)
416 var stackArray = _stateStack.ToArray();
417 info.
AddValue(
"_stateStack", stackArray);
420 base.OnGetState(info, mode);
437 _bindingEdit = info.GetValue<
bool>(
"_bindingEdit");
438 if (info.
Values.ContainsKey(
"_stateStack"))
440 var stackArray = info.GetValue<
byte[][]>(
"_stateStack");
442 foreach (var item
in stackArray.Reverse())
443 _stateStack.Push(item);
446 base.OnSetState(info, mode);
This class implements INotifyPropertyChanged and INotifyPropertyChanging in a serialization-safe mann...
Defines a dictionary that can be serialized through the SerializationFormatterFactory....
bool Contains(K key)
Gets a value indicating whether the dictionary contains the specified key value.
Exception indicating a problem with the use of the n-level undo feature in CSLA .NET.
Implements n-level undo capabilities as described in Chapters 2 and 3.
bool BindingEdit
Gets or sets a value indicating whether n-level undo was invoked through IEditableObject.
virtual void CopyingState()
This method is invoked before the CopyState operation begins.
virtual void UndoingChanges()
This method is invoked after the UndoChanges operation is complete.
virtual void CopyStateComplete()
This method is invoked after the CopyState operation is complete.
virtual void AcceptChangesComplete()
This method is invoked after the AcceptChanges operation is complete.
override void OnGetState(SerializationInfo info, StateMode mode)
Override this method to insert your field values into the MobileFormatter serialzation stream.
UndoableBase()
Creates an instance of the object.
override void OnSetState(SerializationInfo info, StateMode mode)
Override this method to retrieve your field values from the MobileFormatter serialzation stream.
virtual void UndoChangesComplete()
This method is invoked before the UndoChanges operation begins.
virtual void AcceptingChanges()
This method is invoked before the AcceptChanges operation begins.
A strongly-typed resource class, for looking up localized strings, etc.
static string EditLevelMismatchException
Looks up a localized string similar to Edit level mismatch in {0}.
Object containing the serialization data for a specific object.
Dictionary< string, FieldData > Values
Dictionary containg field data.
void AddValue(string name, object value)
Adds a value to the serialization stream.
Defines the methods required to participate in n-level undo within the CSLA .NET framework.
void CopyState(int parentEditLevel, bool parentBindingEdit)
Copies the state of the object and places the copy onto the state stack.
int EditLevel
Gets the current edit level of the object.
Interface to be implemented by any object that supports serialization by the SerializationFormatterFa...
StateMode
Indicates the reason the MobileFormatter functionality has been invoked.
@ Serializable
Prevents updating or inserting until the transaction is complete.