using System; using System.Collections; using System.ComponentModel; namespace CSLA.Core { /// /// This is a base class that exposes an implementation /// of IBindableList that does nothing other than /// create a nonserialized version of the listchanged /// event. /// [Serializable] public abstract class BindableCollectionBase : CollectionBase, IBindingList { #region Protected control variables /// /// Set this to True to allow data binding to add new /// child objects to the collection. /// /// /// If you set this to True, you must also override the OnAddNew /// method. You must also set AllowEdit to True. /// protected bool AllowNew = false; /// /// Set this to True to allow data binding to do in-place /// editing of child objects in a grid control. /// protected bool AllowEdit = false; /// /// Set this to True to allow data binding to automatically /// remove child objects from the collection. /// protected bool AllowRemove = false; /// /// Set this to True to allow this collection to be sorted. /// /// /// /// There is an overhead cost to enabling sorting. Specifically, /// the collection must contain an internal collection containing /// the original order of the items in the collection, so the order /// can be reset if the sort is removed. /// /// This overhead is only incurred if AllowSort is set to True, and is /// only a major concern if you are using a remote DataPortal. The concern /// there is that this extra collection must also be serialized, thus /// increasing the overall amount of data sent across the wire. /// /// protected bool AllowSort = false; /// /// Set this to True to allow this collection to be /// searched. /// protected bool AllowFind = false; #endregion #region ListChanged event /// /// Declares a serialization-safe ListChanged event. /// [field: NonSerialized] public event System.ComponentModel.ListChangedEventHandler ListChanged; /// /// Call this method to raise the ListChanged event. /// virtual protected void OnListChanged(System.ComponentModel.ListChangedEventArgs e) { if (ListChanged != null) ListChanged(this, e); } #endregion #region Collection events // ******************************************************************* /// /// Ensures that the OnListChanged event is raised when a /// new child is inserted. /// override protected void OnInsertComplete(int index, object value) { OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index)); } /// /// Ensures that the OnListChanged event is raised when the /// list is cleared. /// override protected void OnClearComplete() { OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0)); } /// /// Ensures that the OnListChanged event is raised when an /// item is removed. /// override protected void OnRemoveComplete(int index, object value) { OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index)); } /// /// Ensures that the OnListChanged event is raised when an /// item is changed. /// override protected void OnSetComplete(int index, object oldValue, object newValue) { OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index)); } #endregion #region IBindingList interface // ******************************************************************* // This is most of the IBindingList interface. // Notice that each of these implementations merely // calls a virtual method, so subclasses can override those // methods and provide the actual implementation of the interface object IBindingList.AddNew() { return OnAddNew(); } bool IBindingList.AllowEdit { get { return AllowEdit; } } bool IBindingList.AllowNew { get { return AllowNew; } } bool IBindingList.AllowRemove { get { return AllowRemove; } } bool IBindingList.SupportsSearching { get { return AllowFind; } } bool IBindingList.SupportsSorting { get { return AllowSort; } } bool IBindingList.SupportsChangeNotification { get { return true; } } int IBindingList.Find(System.ComponentModel.PropertyDescriptor property, object key) { return IBindingList_Find(property, key); } void IBindingList.AddIndex(System.ComponentModel.PropertyDescriptor property) {} void IBindingList.RemoveIndex(System.ComponentModel.PropertyDescriptor property) {} void IBindingList.ApplySort(System.ComponentModel.PropertyDescriptor property, System.ComponentModel.ListSortDirection direction) { IBindingList_ApplySort(property, direction); } void IBindingList.RemoveSort() { IBindingList_RemoveSort(); } bool IBindingList.IsSorted { get { return IBindingList_IsSorted; } } System.ComponentModel.ListSortDirection IBindingList.SortDirection { get { return IBindingList_SortDirection; } } System.ComponentModel.PropertyDescriptor IBindingList.SortProperty { get { return IBindingList_SortProperty; } } #endregion #region OnAddNew // ******************************************************************* // The following methods allow a subclass to actually provide // the implementation of adding a new child object /// /// Override this method to allow data binding to automatically /// add new child objects to a collection. /// /// virtual protected object OnAddNew() { return null; } #endregion #region Search/Find // ******************************************************************* // The following methods allow a subclass to actually provide // the implementation of IBindingList searching /// /// Override this method to implement search/find functionality /// for the collection. /// /// The property to search. /// The value to searched for. /// protected virtual int IBindingList_Find(PropertyDescriptor property, object key) { return -1; } #endregion #region Sorting // ******************************************************************* // The following methods allow a subclass to actually provide // the implementation of IBindingList sorting /// /// Override this method to indicate whether your collection /// is currently sorted. This returns False by default. /// protected virtual bool IBindingList_IsSorted { get{ return false;}} /// /// Override this method to return the property by which /// the collection is sorted (if you implement sorting). /// protected virtual System.ComponentModel.PropertyDescriptor IBindingList_SortProperty { get{ return null;}} /// /// Override this method to return the current sort direction /// (if you implement sorting). /// protected virtual ListSortDirection IBindingList_SortDirection { get{ return ListSortDirection.Ascending;}} /// /// Override this method to provide sorting functionality /// (if you implement sorting). /// /// The property on which to sort. /// The sort direction. protected virtual void IBindingList_ApplySort(PropertyDescriptor property, ListSortDirection direction) {} /// /// Override this method to remove any existing sort /// (if you implement sorting). /// protected virtual void IBindingList_RemoveSort() {} #endregion } }