diff Source/EditableObjects/EditableObject.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/EditableObjects/EditableObject.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,301 @@
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Data.SqlTypes;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Xml;
+using System.Xml.Serialization;
+
+using BLToolkit.Common;
+using BLToolkit.ComponentModel;
+using BLToolkit.Mapping;
+using BLToolkit.Reflection;
+using BLToolkit.TypeBuilder;
+using BLToolkit.Validation;
+
+namespace BLToolkit.EditableObjects
+{
+	#region Instance Types
+	[GlobalInstanceType(typeof(byte),     typeof(EditableValue<byte>))]
+	[GlobalInstanceType(typeof(char),     typeof(EditableValue<char>))]
+	[GlobalInstanceType(typeof(ushort),   typeof(EditableValue<ushort>))]
+	[GlobalInstanceType(typeof(uint),     typeof(EditableValue<uint>))]
+	[GlobalInstanceType(typeof(ulong),    typeof(EditableValue<ulong>))]
+	[GlobalInstanceType(typeof(bool),     typeof(EditableValue<bool>))]
+	[GlobalInstanceType(typeof(sbyte),    typeof(EditableValue<sbyte>))]
+	[GlobalInstanceType(typeof(short),    typeof(EditableValue<short>))]
+	[GlobalInstanceType(typeof(int),      typeof(EditableValue<int>))]
+	[GlobalInstanceType(typeof(long),     typeof(EditableValue<long>))]
+	[GlobalInstanceType(typeof(float),    typeof(EditableValue<float>))]
+	[GlobalInstanceType(typeof(double),   typeof(EditableValue<double>))]
+	[GlobalInstanceType(typeof(string),   typeof(EditableValue<string>), "")]
+	[GlobalInstanceType(typeof(DateTime), typeof(EditableValue<DateTime>))]
+	[GlobalInstanceType(typeof(decimal),  typeof(EditableValue<decimal>))]
+	[GlobalInstanceType(typeof(Guid),     typeof(EditableValue<Guid>))]
+
+	[GlobalInstanceType(typeof(byte?),     typeof(EditableValue<byte?>))]
+	[GlobalInstanceType(typeof(char?),     typeof(EditableValue<char?>))]
+	[GlobalInstanceType(typeof(ushort?),   typeof(EditableValue<ushort?>))]
+	[GlobalInstanceType(typeof(uint?),     typeof(EditableValue<uint?>))]
+	[GlobalInstanceType(typeof(ulong?),    typeof(EditableValue<ulong?>))]
+	[GlobalInstanceType(typeof(bool?),     typeof(EditableValue<bool?>))]
+	[GlobalInstanceType(typeof(sbyte?),    typeof(EditableValue<sbyte?>))]
+	[GlobalInstanceType(typeof(short?),    typeof(EditableValue<short?>))]
+	[GlobalInstanceType(typeof(int?),      typeof(EditableValue<int?>))]
+	[GlobalInstanceType(typeof(long?),     typeof(EditableValue<long?>))]
+	[GlobalInstanceType(typeof(float?),    typeof(EditableValue<float?>))]
+	[GlobalInstanceType(typeof(double?),   typeof(EditableValue<double?>))]
+	[GlobalInstanceType(typeof(DateTime?), typeof(EditableValue<DateTime?>))]
+	[GlobalInstanceType(typeof(decimal?),  typeof(EditableValue<decimal?>))]
+	[GlobalInstanceType(typeof(Guid?),     typeof(EditableValue<Guid?>))]
+
+	[GlobalInstanceType(typeof(SqlBoolean),  typeof(EditableValue<SqlBoolean>))]
+	[GlobalInstanceType(typeof(SqlByte),     typeof(EditableValue<SqlByte>))]
+	[GlobalInstanceType(typeof(SqlDateTime), typeof(EditableValue<SqlDateTime>))]
+	[GlobalInstanceType(typeof(SqlDecimal),  typeof(EditableValue<SqlDecimal>))]
+	[GlobalInstanceType(typeof(SqlDouble),   typeof(EditableValue<SqlDouble>))]
+	[GlobalInstanceType(typeof(SqlGuid),     typeof(EditableValue<SqlGuid>))]
+	[GlobalInstanceType(typeof(SqlInt16),    typeof(EditableValue<SqlInt16>))]
+	[GlobalInstanceType(typeof(SqlInt32),    typeof(EditableValue<SqlInt32>))]
+	[GlobalInstanceType(typeof(SqlInt64),    typeof(EditableValue<SqlInt64>))]
+	[GlobalInstanceType(typeof(SqlMoney),    typeof(EditableValue<SqlMoney>))]
+	[GlobalInstanceType(typeof(SqlSingle),   typeof(EditableValue<SqlSingle>))]
+	[GlobalInstanceType(typeof(SqlString),   typeof(EditableValue<SqlString>), "")]
+
+	[GlobalInstanceType(typeof(XmlDocument),    typeof(EditableXmlDocument))]
+	[GlobalInstanceType(typeof(EditableObject), typeof(EditableObjectHolder), IsObjectHolder=true)]
+	#endregion
+	[ImplementInterface(typeof(IEditable))]
+	[ImplementInterface(typeof(IMemberwiseEditable))]
+	[ImplementInterface(typeof(IPrintDebugState))]
+	[ImplementInterface(typeof(ISetParent))]
+	[ComVisible(true)]
+	[Serializable]
+	public abstract class EditableObject : EntityBase,
+		ICloneable, IEditableObject, INotifyPropertyChanged,
+		ISupportMapping, IValidatable, IPropertyChanged, INotifyObjectEdit
+	{
+		#region Constructor
+
+		protected EditableObject()
+		{
+			ISetParent setParent = this as ISetParent;
+
+			if (setParent != null)
+				setParent.SetParent(this, null);
+		}
+
+		#endregion
+
+		#region IEditable
+
+		public virtual void AcceptChanges()
+		{
+			if (this is IEditable)
+				((IEditable)this).AcceptChanges();
+		}
+
+		public virtual void RejectChanges()
+		{
+			var dirtyMembers = GetDirtyMembers();
+
+			if (this is IEditable)
+				((IEditable)this).RejectChanges();
+
+			foreach (PropertyInfo dirtyMember in dirtyMembers)
+				OnPropertyChanged(dirtyMember.Name);
+		}
+
+		[MapIgnore, Bindable(false)]
+		public virtual bool IsDirty
+		{
+			get { return this is IEditable? ((IEditable)this).IsDirty: false; }
+		}
+
+		public virtual void AcceptMemberChanges(string memberName)
+		{
+			if (this is IMemberwiseEditable)
+				((IMemberwiseEditable)this).AcceptMemberChanges(null, memberName);
+		}
+
+		public virtual void RejectMemberChanges(string memberName)
+		{
+			bool notifyChange = IsDirtyMember(memberName);
+
+			if (this is IMemberwiseEditable)
+				((IMemberwiseEditable)this).RejectMemberChanges(null, memberName);
+
+			if (notifyChange)
+				OnPropertyChanged(memberName);
+		}
+
+		public virtual bool IsDirtyMember(string memberName)
+		{
+			bool isDirty = false;
+
+			if (this is IMemberwiseEditable)
+				((IMemberwiseEditable)this).IsDirtyMember(null, memberName, ref isDirty);
+
+			return isDirty;
+		}
+
+		public virtual PropertyInfo[] GetDirtyMembers()
+		{
+			ArrayList list = new ArrayList();
+
+			if (this is IMemberwiseEditable)
+				((IMemberwiseEditable)this).GetDirtyMembers(null, list);
+
+			return (PropertyInfo[])list.ToArray(typeof(PropertyInfo));
+		}
+
+		[MapIgnore, Bindable(false)]
+		public virtual string PrintDebugState
+		{
+			get
+			{
+#if DEBUG
+				if (this is IPrintDebugState)
+				{
+					string s = string.Format(
+						"====== {0} ======\r\nIsDirty: {1}\r\n" +
+						"Property       IsDirty Original                                 Current\r\n" +
+						"==================== = ======================================== ========================================\r\n",
+						GetType().Name, IsDirty);
+
+					((IPrintDebugState)this).PrintDebugState(null, ref s);
+
+					return s + "\r\n";
+				}
+#endif
+				return "";
+			}
+		}
+
+		#endregion
+
+		#region ISupportMapping Members
+
+		private bool _isInMapping;
+		[MapIgnore, Bindable(false)]
+		public  bool  IsInMapping
+		{
+			get { return _isInMapping; }
+		}
+
+		protected void SetIsInMapping(bool isInMapping)
+		{
+			_isInMapping = isInMapping;
+		}
+
+		public virtual void BeginMapping(InitContext initContext)
+		{
+			_isInMapping = true;
+		}
+
+		public virtual void EndMapping(InitContext initContext)
+		{
+			if (initContext.IsDestination)
+				AcceptChanges();
+
+			_isInMapping = false;
+
+			if (initContext.IsDestination)
+				OnPropertyChanged("");
+		}
+
+		#endregion
+
+		#region Notify Changes
+
+		protected internal virtual void OnPropertyChanged(string propertyName)
+		{
+			if (NotifyChanges && PropertyChanged != null)
+				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+		}
+
+		private int _notNotifyChangesCount = 0;
+		[MapIgnore, Bindable(false), XmlIgnore]
+		public  bool  NotifyChanges
+		{
+			get { return _notNotifyChangesCount == 0;   }
+			set { _notNotifyChangesCount = value? 0: 1; }
+		}
+
+		public void LockNotifyChanges()
+		{
+			_notNotifyChangesCount++;
+		}
+
+		public void UnlockNotifyChanges()
+		{
+			_notNotifyChangesCount--;
+
+			if (_notNotifyChangesCount < 0)
+				throw new InvalidOperationException();
+		}
+
+		#endregion
+
+		#region IPropertyChanged Members
+
+		void IPropertyChanged.OnPropertyChanged(PropertyInfo propertyInfo)
+		{
+			if (_isInMapping == false)
+				OnPropertyChanged(propertyInfo.Name);
+		}
+
+		#endregion
+
+		#region INotifyPropertyChanged Members
+
+		[field : NonSerialized]
+		public virtual event PropertyChangedEventHandler PropertyChanged;
+
+		#endregion
+
+		#region IEditableObject Members
+
+		public virtual void BeginEdit()
+		{
+			if (ObjectEdit != null)
+				ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Begin));
+		}
+
+		public virtual void CancelEdit()
+		{
+			if (ObjectEdit != null)
+				ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.Cancel));
+		}
+
+		public virtual void EndEdit()
+		{
+			if (ObjectEdit != null)
+				ObjectEdit(this, new ObjectEditEventArgs(ObjectEditType.End));
+		}
+
+		#endregion
+
+		#region INotifyObjectEdit Members
+
+		public event ObjectEditEventHandler ObjectEdit;
+
+		#endregion
+
+		#region ICloneable Members
+
+		///<summary>
+		///Creates a new object that is a copy of the current instance.
+		///</summary>
+		///<returns>
+		///A new object that is a copy of this instance.
+		///</returns>
+		object ICloneable.Clone()
+		{
+			return TypeAccessor.Copy(this);
+		}
+
+		#endregion
+	}
+}