9using System.Collections.Generic;
11using System.ComponentModel;
30 private readonly Stack<byte[]> _stateStack =
new();
32 private bool _bindingEdit;
43 get => _applicationContext;
46 _applicationContext = value;
71 [EditorBrowsable(EditorBrowsableState.Never)]
86 get {
return EditLevel; }
92 [EditorBrowsable(EditorBrowsableState.Never)]
93 protected int EditLevel
95 get {
return _stateStack.Count; }
100 if (!parentBindingEdit)
101 CopyState(parentEditLevel);
104 void IUndoableObject.UndoChanges(
int parentEditLevel,
bool parentBindingEdit)
106 if (!parentBindingEdit)
107 UndoChanges(parentEditLevel);
110 void IUndoableObject.AcceptChanges(
int parentEditLevel,
bool parentBindingEdit)
112 if (!parentBindingEdit)
113 AcceptChanges(parentEditLevel);
120 [EditorBrowsable(EditorBrowsableState.Advanced)]
129 [EditorBrowsable(EditorBrowsableState.Advanced)]
138 [EditorBrowsable(EditorBrowsableState.Never)]
139 protected internal void CopyState(
int parentEditLevel)
143 Type currentType = this.GetType();
146 if (this.EditLevel + 1 > parentEditLevel)
151 var currentTypeName = currentType.FullName;
153 List<DynamicMemberHandle> handlers =
154 UndoableHandler.GetCachedFieldHandlers(currentType);
155 foreach (var h
in handlers)
157 var value = h.DynamicMemberGet(
this);
158 var fieldName = GetFieldName(currentTypeName, h.MemberName);
165 state.Add(fieldName,
null);
170 ((IUndoableObject)value).CopyState(this.EditLevel + 1,
BindingEdit);
176 using MemoryStream buffer =
new MemoryStream();
177 var formatter = SerializationFormatterFactory.GetFormatter(ApplicationContext);
178 formatter.Serialize(buffer, value);
179 state.Add(fieldName, buffer.ToArray());
184 state.Add(fieldName, value);
188 currentType = currentType.BaseType;
192 using (MemoryStream buffer =
new MemoryStream())
194 var formatter = SerializationFormatterFactory.GetFormatter(ApplicationContext);
195 formatter.Serialize(buffer, state);
196 _stateStack.Push(buffer.ToArray());
205 [EditorBrowsable(EditorBrowsableState.Advanced)]
214 [EditorBrowsable(EditorBrowsableState.Advanced)]
229 [EditorBrowsable(EditorBrowsableState.Never)]
230 protected internal void UndoChanges(
int parentEditLevel)
239 if (this.EditLevel - 1 != parentEditLevel)
243 using (MemoryStream buffer =
new MemoryStream(_stateStack.Pop()))
250 Type currentType = this.GetType();
254 var currentTypeName = currentType.FullName;
257 List<DynamicMemberHandle> handlers = UndoableHandler.GetCachedFieldHandlers(currentType);
258 foreach (var h
in handlers)
261 var value = h.DynamicMemberGet(
this);
262 var fieldName = GetFieldName(currentTypeName, h.MemberName);
264 if (typeof(IUndoableObject).IsAssignableFrom(h.MemberType))
272 h.DynamicMemberSet(
this,
null);
280 ((IUndoableObject)value).UndoChanges(this.EditLevel,
BindingEdit);
287 using MemoryStream buffer =
new MemoryStream((
byte[])state[fieldName]);
289 var formatter = SerializationFormatterFactory.GetFormatter(ApplicationContext);
290 var obj = formatter.Deserialize(buffer);
291 h.DynamicMemberSet(
this, obj);
296 h.DynamicMemberSet(
this, state[fieldName]);
300 currentType = currentType.BaseType;
310 [EditorBrowsable(EditorBrowsableState.Advanced)]
319 [EditorBrowsable(EditorBrowsableState.Advanced)]
333 [EditorBrowsable(EditorBrowsableState.Never)]
334 protected internal void AcceptChanges(
int parentEditLevel)
338 if (this.EditLevel - 1 != parentEditLevel)
344 Type currentType = this.GetType();
349 List<DynamicMemberHandle> handlers = UndoableHandler.GetCachedFieldHandlers(currentType);
350 foreach (var h
in handlers)
355 object value = h.DynamicMemberGet(
this);
360 ((Core.IUndoableObject)value).AcceptChanges(this.EditLevel,
BindingEdit);
365 currentType = currentType.BaseType;
377 private static string GetFieldName(
string typeName,
string memberName)
379 return typeName +
"." + memberName;
382 internal static void ResetChildEditLevel(IUndoableObject child,
int parentEditLevel,
bool bindingEdit)
384 int targetLevel = parentEditLevel;
385 if (bindingEdit && targetLevel > 0 && child is not FieldManager.FieldDataManager)
389 while (child.EditLevel > targetLevel)
390 child.AcceptChanges(targetLevel,
false);
393 while (child.EditLevel < targetLevel)
394 child.CopyState(targetLevel,
false);
411 info.
AddValue(
"_bindingEdit", _bindingEdit);
412 if (_stateStack.Count > 0)
414 var stackArray = _stateStack.ToArray();
415 info.
AddValue(
"_stateStack", stackArray);
418 base.OnGetState(info, mode);
435 _bindingEdit = info.GetValue<
bool>(
"_bindingEdit");
436 if (info.
Values.ContainsKey(
"_stateStack"))
438 var stackArray = info.GetValue<
byte[][]>(
"_stateStack");
440 foreach (var item
in stackArray.Reverse())
441 _stateStack.Push(item);
444 base.OnSetState(info, mode);
Provides consistent context information between the client and server DataPortal objects.
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 type.
override void OnSetState(SerializationInfo info, StateMode mode)
Override this method to retrieve your field values from the MobileFormatter serialzation stream.
virtual void OnApplicationContextSet()
Method invoked after ApplicationContext is available.
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.
Implement if a class requires access to the CSLA ApplicationContext type.
ApplicationContext ApplicationContext
Gets or sets the current ApplicationContext 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.