Mercurial > pub > bltoolkit
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 + } +}