void Core.IUndoableObject.UndoChanges(int parentEditLevel, bool parentBindingEdit) { if (EditLevel > 0) { if (this.EditLevel - 1 != parentEditLevel) { throw new UndoException(string.Format(Resources.EditLevelMismatchException, "UndoChanges"), this.GetType().Name, _parent != null ? _parent.GetType().Name : null, this.EditLevel, parentEditLevel + 1); } #if (ANDROID || IOS) || NETFX_CORE || NETSTANDARD2_0 SerializationInfo state = _stateStack.Pop(); OnSetState(state, StateMode.Undo); for (var index = 0; index < _fieldData.Length; index++) { var item = _fieldData[index]; if (item != null) { // potential child object var child = item.Value as IUndoableObject; if (child != null) { child.UndoChanges(parentEditLevel, parentBindingEdit); } } } #else IFieldData[] state = null; using (MemoryStream buffer = new MemoryStream(_stateStack.Pop())) { buffer.Position = 0; var formatter = SerializationFormatterFactory.GetNativeFormatter(); state = (IFieldData[])(formatter.Deserialize(buffer)); } for (var index = 0; index < _fieldData.Length; index++) { var oldItem = state[index]; var item = _fieldData[index]; if (item != null) { var undoable = item.Value as IUndoableObject; if (undoable != null) { // current value is undoable if (oldItem != null) { undoable.UndoChanges(parentEditLevel, parentBindingEdit); } else { _fieldData[index] = null; } continue; } } // restore IFieldData object into field collection _fieldData[index] = oldItem; } #endif } }
void Core.IUndoableObject.CopyState(int parentEditLevel, bool parentBindingEdit) { if (this.EditLevel + 1 > parentEditLevel) { throw new UndoException(string.Format(Resources.EditLevelMismatchException, "CopyState"), this.GetType().Name, _parent != null ? _parent.GetType().Name : null, this.EditLevel, parentEditLevel - 1); } #if (ANDROID || IOS) || NETFX_CORE || NETSTANDARD2_0 SerializationInfo state = new SerializationInfo(0); OnGetState(state, StateMode.Undo); // This is used instead of a foreach because of some weird silverlight bug // throwing an unknown exception from a foreach here. for (var index = 0; index < _fieldData.Length; index++) { var item = _fieldData[index]; if (item != null) { var child = item.Value as IUndoableObject; if (child != null) { // cascade call to child child.CopyState(parentEditLevel, parentBindingEdit); } } } _stateStack.Push(state); #else IFieldData[] state = new IFieldData[_propertyList.Count]; for (var index = 0; index < _fieldData.Length; index++) { var item = _fieldData[index]; if (item != null) { var child = item.Value as IUndoableObject; if (child != null) { // cascade call to child child.CopyState(parentEditLevel, parentBindingEdit); // indicate that there was a value here state[index] = new FieldData <bool>(item.Name); } else { // add the IFieldData object state[index] = item; } } } // serialize the state and stack it using (MemoryStream buffer = new MemoryStream()) { var formatter = SerializationFormatterFactory.GetNativeFormatter(); formatter.Serialize(buffer, state); _stateStack.Push(buffer.ToArray()); } #endif }