diff Source/ComponentModel/ObjectBinder.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/ComponentModel/ObjectBinder.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,547 @@
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing.Design;
+using System.Drawing;
+using System.Windows.Forms;
+
+using BLToolkit.EditableObjects;
+using BLToolkit.Reflection;
+
+namespace BLToolkit.ComponentModel
+{
+	/// <summary>
+	/// http://www.bltoolkit.net/Doc/ComponentModel/ObjectBinder.htm
+	/// </summary>
+	//[ComplexBindingProperties("DataSource", "DataMember")]
+	[ComplexBindingProperties("DataSource")]
+	[DefaultProperty("ItemType")]
+	[ToolboxItem(true)]
+	[ToolboxBitmap(typeof(ObjectBinder))]
+	public class ObjectBinder : Component, ITypedList, IBindingListView, ICancelAddNew
+	{
+		#region Constructors
+
+		static readonly EditableArrayList _empty = new EditableArrayList(typeof(object));
+
+		public ObjectBinder()
+		{
+		}
+
+		public ObjectBinder(IContainer container)
+			: this()
+		{
+			if (container != null)
+				container.Add(this);
+		}
+
+		#endregion
+
+		#region Public members
+
+		private object _dataSource;
+
+		[AttributeProvider(typeof(IListSource))]
+		[RefreshProperties(RefreshProperties.Repaint)]
+		[DefaultValue(null)]
+		[Category("Data")]
+		public  object  DataSource
+		{
+			get { return _dataSource; }
+			set
+			{
+				_dataSource = value;
+
+				if      (value is Type)          ItemType   = (Type)value;
+				else if (value is BindingSource) DataSource = ((BindingSource)value).DataSource;
+				else if (value is IList)         List       = (IList)value;
+				else if (value is IListSource)   List       = ((IListSource)value).GetList();
+				else                             Object     = value;
+			}
+		}
+
+		private Type _itemType;
+		[RefreshProperties(RefreshProperties.Repaint)]
+		[DefaultValue(null)]
+		[Category("Data")]
+		[TypeConverter(typeof(TypeTypeConverter))]
+#if !CLIENTPROFILE
+		[Editor(typeof(Design.TypeEditor), typeof(UITypeEditor))]
+#endif
+		public  Type  ItemType
+		{
+			get { return _itemType; }
+			set
+			{
+				_itemType = value;
+
+				List = null;
+
+				OnListChanged(ListChangedType.PropertyDescriptorChanged, -1);
+			}
+		}
+
+		private Type _objectViewType;
+		[RefreshProperties(RefreshProperties.Repaint)]
+		[DefaultValue(null)]
+		[Category("Data")]
+		[TypeConverter(typeof(TypeTypeConverter))]
+#if !CLIENTPROFILE
+		[Editor(typeof(Design.ObjectViewTypeEditor), typeof(UITypeEditor))]
+#endif
+		public  Type  ObjectViewType
+		{
+			get { return _objectViewType; }
+			set
+			{
+				_objectViewType = value;
+
+				List = null;
+
+				OnListChanged(ListChangedType.PropertyDescriptorChanged, -1);
+			}
+		}
+
+		private object _object;
+		[Browsable(false)]
+		[RefreshProperties(RefreshProperties.Repaint)]
+		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+		public object Object
+		{
+			get { return _object; }
+			set
+			{
+				if (value == null)
+				{
+					List = null;
+				}
+				else
+				{
+					EditableArrayList list = new EditableArrayList(value.GetType(), 1);
+
+					list.Add(value, false);
+
+					List = list;
+					_object = value;
+				}
+			}
+		}
+
+		private bool              _isListCreatedInternally;
+		private EditableArrayList _list = _empty;
+		[Browsable(false)]
+		[RefreshProperties(RefreshProperties.Repaint)]
+		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+		public IList List
+		{
+			get { return _list; }
+			set
+			{
+				if (value == null)
+				{
+					if (_list != _empty)
+						_list.ListChanged -= ListChangedHandler;
+
+					_list = _itemType == null? _empty: new EditableArrayList(_itemType);
+					_isListCreatedInternally = true;
+				}
+				else
+				{
+					EditableArrayList list;
+
+					if (value is EditableArrayList)
+					{
+						list = (EditableArrayList)value;
+
+						_isListCreatedInternally = false;
+					}
+					else
+					{
+						if (value.Count != 0 && _itemType == null)
+							list = EditableArrayList.Adapter(value);
+						else
+							list = EditableArrayList.Adapter(_itemType, value);
+
+						_isListCreatedInternally = true;
+					}
+
+					if (_itemType == null)
+					{
+						_itemType = list.ItemType;
+					}
+					else
+					{
+						if (list.ItemType != _itemType && !list.ItemType.IsSubclassOf(_itemType))
+							throw new ArgumentException(string.Format(
+								"Item type {0} of the new list must be a subclass of {1}.",
+								list.ItemType,
+								_itemType));
+					}
+
+					if (_list != _empty)
+					{
+						_list.ListChanged -= ListChangedHandler;
+						
+						if (_disposeList || (_isListCreatedInternally && _disposeCreatedList))
+							_list.Dispose();
+					}
+
+					_list = list;
+				}
+
+				if (_list != _empty)
+					_list.ListChanged += ListChangedHandler;
+
+				OnListChanged(ListChangedType.Reset, -1);
+			}
+		}
+
+		private bool _disposeList;
+		[DefaultValue(false)]
+		[Category("Behavior")]
+		[Description("Determines whether ObjectBinder will invoke underlying List's dispose when being itself disposed.")]
+		public bool DisposeList
+		{
+			get { return _disposeList;  }
+			set { _disposeList = value; }
+		}
+
+		private bool _disposeCreatedList = true;
+		[DefaultValue(true)]
+		[Category("Behavior")]
+		[Description("Determines whether ObjectBinder will invoke underlying internally created List's dispose when being itself disposed")]
+		public bool DisposeCreatedList
+		{
+			get { return _disposeCreatedList;  }
+			set { _disposeCreatedList = value; }
+		}
+
+		private bool _allowNew = true;
+		[DefaultValue(true)]
+		[Category("Behavior")]
+		[Description("Determines whether new items can be added to the list.")]
+		public  bool  AllowNew
+		{
+			get { return _allowNew && _list.AllowNew;  }
+			set { _allowNew = value; }
+		}
+
+		private bool _allowEdit = true;
+		[DefaultValue(true)]
+		[Category("Behavior")]
+		[Description("Determines whether items in the list can be edited.")]
+		public  bool  AllowEdit
+		{
+			get { return _allowEdit && _list.AllowEdit; }
+			set { _allowEdit = value; }
+		}
+
+		private bool _allowRemove = true;
+		[DefaultValue(true)]
+		[Category("Behavior")]
+		[Description("Determines whether items can be removed from the list.")]
+		public bool AllowRemove
+		{
+			get { return _allowRemove && _list.AllowRemove;  }
+			set { _allowRemove = value; }
+		}
+
+		private IsNullHandler _isNull;
+		[Browsable(false)]
+		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+		public  IsNullHandler  IsNull
+		{
+			get { return _isNull;  }
+			set { _isNull = value; }
+		}
+
+		bool IBindingList.AllowNew    { get { return AllowNew;    } }
+		bool IBindingList.AllowEdit   { get { return AllowEdit;   } }
+		bool IBindingList.AllowRemove { get { return AllowRemove; } }
+
+		#endregion
+
+		#region Protected Members
+
+		protected virtual void OnListChanged(ListChangedEventArgs e)
+		{
+			ListChangedEventHandler handler = (ListChangedEventHandler)Events[ListChangedEvent];
+			if (handler != null)
+				handler(this, e);
+		}
+
+		protected void OnListChanged(ListChangedType listChangedType, int newIndex)
+		{
+			OnListChanged(new ListChangedEventArgs(listChangedType, newIndex));
+		}
+
+		private void ListChangedHandler(object sender, ListChangedEventArgs e)
+		{
+			OnListChanged(e);
+		}
+
+		protected override void Dispose(bool disposing)
+		{
+			if (_list != _empty)
+			{
+				_list.ListChanged -= ListChangedHandler;
+
+				if (_disposeList || (_isListCreatedInternally && _disposeCreatedList))
+					_list.Dispose();
+			}
+
+			_list = _empty;
+			
+			base.Dispose(disposing);
+		}
+
+		#endregion
+
+		#region ITypedList Members
+
+		private static readonly Hashtable _descriptors = new Hashtable();
+
+		PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
+		{
+			if (_itemType == null)
+				return new PropertyDescriptorCollection(new PropertyDescriptor[0]);
+
+			string key =
+				_itemType + "." +
+				(_objectViewType == null? string.Empty: _objectViewType.ToString()) + "." +
+				(_isNull == null? "0": "1");
+
+			if (listAccessors != null)
+				foreach (PropertyDescriptor pd in listAccessors)
+					key += "." + pd.Name;
+
+			PropertyDescriptorCollection pdc = (PropertyDescriptorCollection)_descriptors[key];
+
+			if (pdc == null)
+			{
+				pdc = _list.GetItemProperties(listAccessors, _objectViewType, _isNull, !DesignMode);
+
+				if (!DesignMode)
+					_descriptors[key] = pdc;
+			}
+
+			return pdc;
+		}
+
+		string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
+		{
+			return _list.GetListName(listAccessors);
+		}
+
+		#endregion
+
+		#region IBindingListView Members
+
+		bool IBindingListView.SupportsAdvancedSorting
+		{
+			get { return _list.SupportsAdvancedSorting; }
+		}
+
+		ListSortDescriptionCollection IBindingListView.SortDescriptions
+		{
+			get { return _list.SortDescriptions; }
+		}
+
+		void IBindingListView.ApplySort(ListSortDescriptionCollection sorts)
+		{
+			_list.ApplySort(sorts);
+		}
+
+		bool IBindingListView.SupportsFiltering
+		{
+			get { return _list.SupportsFiltering; }
+		}
+
+		string IBindingListView.Filter
+		{
+			get { return _list.Filter;  }
+			set { _list.Filter = value; }
+		}
+
+		void IBindingListView.RemoveFilter()
+		{
+			_list.RemoveFilter();
+		}
+
+		#endregion
+
+		#region ICancelAddNew Members
+
+		void ICancelAddNew.CancelNew(int itemIndex)
+		{
+			_list.CancelNew(itemIndex);
+		}
+
+		void ICancelAddNew.EndNew(int itemIndex)
+		{
+			_list.EndNew(itemIndex);
+		}
+
+		#endregion
+
+		#region IBindingList Members
+
+		void IBindingList.AddIndex(PropertyDescriptor property)
+		{
+			_list.AddIndex(property);
+		}
+
+		object IBindingList.AddNew()
+		{
+			return _list.AddNew();
+		}
+
+		void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
+		{
+			_list.ApplySort(property, direction);
+		}
+
+		int IBindingList.Find(PropertyDescriptor property, object key)
+		{
+			return _list.Find(property, key);
+		}
+
+		bool IBindingList.IsSorted
+		{
+			get { return _list.IsSorted; }
+		}
+
+		private static readonly object ListChangedEvent = new object();
+
+		public event ListChangedEventHandler ListChanged
+		{
+			add    { Events.AddHandler   (ListChangedEvent, value); }
+			remove { Events.RemoveHandler(ListChangedEvent, value); }
+		}
+
+		void IBindingList.RemoveIndex(PropertyDescriptor property)
+		{
+			_list.RemoveIndex(property);
+		}
+
+		void IBindingList.RemoveSort()
+		{
+			_list.RemoveSort();
+		}
+
+		ListSortDirection IBindingList.SortDirection
+		{
+			get { return _list.SortDirection; }
+		}
+
+		PropertyDescriptor IBindingList.SortProperty
+		{
+			get { return _list.SortProperty; }
+		}
+
+		bool IBindingList.SupportsChangeNotification
+		{
+			get { return _list.SupportsChangeNotification; }
+		}
+
+		bool IBindingList.SupportsSearching
+		{
+			get { return _list.SupportsSearching; }
+		}
+
+		bool IBindingList.SupportsSorting
+		{
+			get { return _list.SupportsSorting; }
+		}
+
+		#endregion
+
+		#region IList Members
+
+		int IList.Add(object value)
+		{
+			return _list.Add(value);
+		}
+
+		void IList.Clear()
+		{
+			_list.Clear();
+		}
+
+		bool IList.Contains(object value)
+		{
+			return _list.Contains(value);
+		}
+
+		int IList.IndexOf(object value)
+		{
+			return _list.IndexOf(value);
+		}
+
+		void IList.Insert(int index, object value)
+		{
+			_list.Insert(index, value);
+		}
+
+		bool IList.IsFixedSize
+		{
+			get { return _list.IsFixedSize; }
+		}
+
+		bool IList.IsReadOnly
+		{
+			get { return _list.IsReadOnly; }
+		}
+
+		void IList.Remove(object value)
+		{
+			_list.Remove(value);
+		}
+
+		void IList.RemoveAt(int index)
+		{
+			_list.RemoveAt(index);
+		}
+
+		object IList.this[int index]
+		{
+			get { return index == -1? null: _list[index];  }
+			set { _list[index] = value; }
+		}
+
+		#endregion
+
+		#region ICollection Members
+
+		void ICollection.CopyTo(Array array, int index)
+		{
+			_list.CopyTo(array, index);
+		}
+
+		int ICollection.Count
+		{
+			get { return _list.Count; }
+		}
+
+		bool ICollection.IsSynchronized
+		{
+			get { return _list.IsSynchronized; }
+		}
+
+		object ICollection.SyncRoot
+		{
+			get { return _list.SyncRoot; }
+		}
+
+		#endregion
+
+		#region IEnumerable Members
+
+		IEnumerator IEnumerable.GetEnumerator()
+		{
+			return _list.GetEnumerator();
+		}
+
+		#endregion
+	}
+}