using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
namespace WebAuditBLL.Core
{
public class SortedBindingList < T > : IList < T > , IBindingList, IEnumerable < T > , ICancelAddNew
{
#region 字段与属性
// 源列表IList
private IList < T > m_lsList;
// 源列表IBindingList
private IBindingList m_lsBindingList;
// 是否已排了序
private bool m_bSorted;
// 是否提供可邦定源
private bool m_bSupportsBinding;
private bool m_bInitiatedLocally;
// 参与属性描述器
private PropertyDescriptor m_objSortByPro;
// 不参与排序的属性描述器
private PropertyDescriptor m_objNotSortPro;
// 不参与排序的属性描述器等于这些值不参与排序
private string [] m_aryThisValueNotSort;
// 不参与排序的属性名
private string [] m_aryNotSortStr;
// 排序方向
private ListSortDirection m_objOrderDirect = ListSortDirection.Ascending;
// 排序列表
private List < ListItem > m_lstSortIndex = new List < ListItem > ();
// 最后一个是否参与排序
private bool m_bIsSortLast = true ;
/// <summary>
/// 项发生变化的事件
/// </summary>
public event ListChangedEventHandler ListChanged;
/// <summary>
/// 当BIsSortLast为flase时或对某些指定值的行不作排序(即用于构造函数3)才可能发出此事件,这事件作用是用来设置“合计”,“小计”那行的风格
/// </summary>
public event ListChangedEventHandler ListChangedForIsSortLast;
/// <summary>
/// 原数据源
/// </summary>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public IList < T > SourceList
{
get
{
return m_lsList;
}
}
/// <summary>
/// 是否已排了序
/// </summary>
public bool IsSorted
{
get
{
return m_bSorted;
}
}
/// <summary>
/// 最后一个是否参与排序
/// </summary>
public bool BIsSortLast
{
get { return m_bIsSortLast; }
set { m_bIsSortLast = value; }
}
#endregion
/// <summary>
/// 构造函数1
/// </summary>
/// <param name="list"></param>
public SortedBindingList(IList < T > lsList)
{
m_lsList = lsList;
if (m_lsList is IBindingList)
{
m_bSupportsBinding = true ;
m_lsBindingList = (IBindingList)m_lsList;
m_lsBindingList.ListChanged += new ListChangedEventHandler(SourceChanged);
}
}
/// <summary>
/// 构造函数2
/// </summary>
/// <param name="lsList"></param>
/// <param name="bF"> 该参数的插入只是为了区分构造函数3,可为任意值 </param>
/// <param name="aryNotSortStr"> 不参与排序的属性名列表 </param>
public SortedBindingList(IList < T > lsList, bool bF, params string [] aryNotSortStr)
{
m_lsList = lsList;
if (m_lsList is IBindingList)
{
m_bSupportsBinding = true ;
m_lsBindingList = (IBindingList)m_lsList;
m_lsBindingList.ListChanged += new ListChangedEventHandler(SourceChanged);
}
if (aryNotSortStr != null )
m_aryNotSortStr = aryNotSortStr;
}
/// <summary>
/// 构造函数3,第二个参数是属性名且属性类型是string
/// </summary>
/// <param name="lsList"> 数据源 </param>
/// <param name="sPropertyName"> 指定不参与排序的属性名且属性类型只能是string,不支持其它类型 </param>
/// <param name="aryThisValueNotSort"> 第二个参数属性等于这些值时不参与排序 </param>
public SortedBindingList(IList < T > lsList, string sPropertyName, params string [] aryThisValueNotSort)
{
m_lsList = lsList;
if (m_lsList is IBindingList)
{
m_bSupportsBinding = true ;
m_lsBindingList = (IBindingList)m_lsList;
m_lsBindingList.ListChanged += new ListChangedEventHandler(SourceChanged);
}
m_objNotSortPro = null ;
if ( ! String.IsNullOrEmpty(sPropertyName))
{
Type itemType = typeof (T);
foreach (PropertyDescriptor it in TypeDescriptor.GetProperties(itemType))
{
if (it.Name == sPropertyName)
{
m_objNotSortPro = it;
break ;
}
}
}
if (aryThisValueNotSort != null )
m_aryThisValueNotSort = aryThisValueNotSort;
}
/// <summary>
/// 列表更改或列表中的项更改时发生时处理函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SourceChanged( object sender, ListChangedEventArgs e)
{
if (m_bSorted)
{
switch (e.ListChangedType)
{
case ListChangedType.ItemAdded:
T newItem = m_lsList[e.NewIndex];
if (e.NewIndex == m_lsList.Count - 1 )
{
object newKey;
if (m_objSortByPro != null )
newKey = m_objSortByPro.GetValue(newItem);
else
newKey = newItem;
if (m_objOrderDirect == ListSortDirection.Ascending)
m_lstSortIndex.Add( new ListItem(newKey, e.NewIndex));
else
m_lstSortIndex.Insert( 0 , new ListItem(newKey, e.NewIndex));
if ( ! m_bInitiatedLocally)
OnListChanged( new ListChangedEventArgs(ListChangedType.ItemAdded, SortedIndex(e.NewIndex)));
}
else
DoSort();
break ;
case ListChangedType.ItemChanged:
OnListChanged( new ListChangedEventArgs(ListChangedType.ItemChanged, SortedIndex(e.NewIndex), e.PropertyDescriptor));
break ;
case ListChangedType.ItemDeleted:
if ( ! m_bInitiatedLocally)
DoSort();
break ;
default :
if ( ! m_bInitiatedLocally)
DoSort();
break ;
}
}
else
OnListChanged(e);
}
#region IBindingList, IList<T> 成员
/// <summary>
/// 对列有进行排序
/// </summary>
/// <param name="sPropertyName"></param>
/// <param name="objDirection"></param>
public void ApplySort( string sPropertyName, ListSortDirection objDirection)
{
m_objSortByPro = null ;
if ( ! String.IsNullOrEmpty(sPropertyName))
{
Type itemType = typeof (T);
foreach (PropertyDescriptor it in TypeDescriptor.GetProperties(itemType))
{
if (it.Name == sPropertyName)
{
m_objSortByPro = it;
break ;
}
}
}
ApplySort(m_objSortByPro, objDirection);
}
/// <summary>
/// 对列有进行排序--实现IBindingList接口
/// </summary>
/// <param name="objProperty"></param>
/// <param name="objDirection"></param>
public void ApplySort(PropertyDescriptor objProperty, ListSortDirection objDirection)
{
if (m_aryNotSortStr != null )
foreach ( string it in m_aryNotSortStr)
if (objProperty.Name == it)
return ;
m_objSortByPro = objProperty;
m_objOrderDirect = objDirection;
// ===================================
if (m_objNotSortPro != null && (m_aryThisValueNotSort != null || m_aryThisValueNotSort.Length > 0 ))
{
List < T > lsTemp = new List < T > ();
var pExcept = from i in m_lsList where m_aryThisValueNotSort.Contains(m_objNotSortPro.GetValue(i).ToString()) select i;
lsTemp = pExcept.Cast < T > ().ToList();
for ( int i = 0 ; i < lsTemp.Count; i ++ )
m_lsList.RemoveAt(m_lsList.Count - 1 );
DoSort();
foreach (T obj in lsTemp)
m_lsList.Add(obj);
// Dictionary<int, T> dicTemp = new Dictionary<int,T>();
// dicTemp.Clear();
// int i = 0;
// foreach (T obj in m_lsList)
// {
// foreach (string it in m_aryThisValueNotSort)
// if (m_objNotSortPro.GetValue(obj).ToString() == it)
// {
// if (!dicTemp.ContainsKey(i))
// dicTemp.Add(i, obj);
// break;
// }
// i++;
// }
// List<int> lsInt = dicTemp.Keys.ToList();
// lsInt.Sort();
// for (int j = 0; j < lsInt.Count; j++)
// {
// m_lsList.RemoveAt(lsInt[j] - j);
// }
// foreach (int nKey in dicTemp.Keys)
// m_lsList.Add(dicTemp[nKey]);
OnListChangedForIsSortLast( new ListChangedEventArgs(ListChangedType.Reset, 0 ));
return ;
}
// ============================
if (m_bIsSortLast)
DoSort();
else
{
T objT = m_lsList[m_lsList.Count - 1 ];
m_lsList.RemoveAt(m_lsList.Count - 1 );
DoSort();
m_lsList.Add(objT);
}
if (m_bIsSortLast == false )
OnListChangedForIsSortLast( new ListChangedEventArgs(ListChangedType.Reset, 0 ));
}
/// <summary>
/// 返回具有给定 System.ComponentModel.PropertyDescriptor 的行的索引
/// </summary>
/// <param name="sPropertyName"></param>
/// <param name="key"></param>
/// <returns></returns>
public int Find( string sPropertyName, object key)
{
PropertyDescriptor objFindProperty = null ;
if ( ! String.IsNullOrEmpty(sPropertyName))
{
Type itemType = typeof (T);
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(itemType))
{
if (prop.Name == sPropertyName)
{
objFindProperty = prop;
break ;
}
}
}
return Find(objFindProperty, key);
}
/// <summary>
/// 激发ListChanged事件
/// </summary>
/// <param name="e"></param>
protected void OnListChanged(ListChangedEventArgs e)
{
if (ListChanged != null )
ListChanged( this , e);
}
protected void OnListChangedForIsSortLast(ListChangedEventArgs e)
{
if (ListChangedForIsSortLast != null )
ListChangedForIsSortLast( this , e);
}
/// <summary>
/// 返回具有给定 System.ComponentModel.PropertyDescriptor 的行的索引--实现IBindingList接口
/// </summary>
/// <param name="property"></param>
/// <param name="key"></param>
/// <returns></returns>
public int Find(PropertyDescriptor objProperty, object objKey)
{
if (m_bSupportsBinding)
return SortedIndex(m_lsBindingList.Find(objProperty, objKey));
else
return - 1 ;
}
/// <summary>
/// 撤销排序--实现IBindingList接口
/// </summary>
public void RemoveSort()
{
UndoSort();
}
/// <summary>
/// 添加到用于搜索的索引--实现IBindingList接口
/// </summary>
/// <param name="objProperty"></param>
public void AddIndex(PropertyDescriptor objProperty)
{
if (m_bSupportsBinding)
m_lsBindingList.AddIndex(objProperty);
}
/// <summary>
/// 将新项添加到列表--实现IBindingList接口
/// </summary>
/// <returns></returns>
public object AddNew()
{
object result;
if (m_bSupportsBinding)
{
m_bInitiatedLocally = true ;
result = m_lsBindingList.AddNew();
m_bInitiatedLocally = false ;
OnListChanged( new ListChangedEventArgs(ListChangedType.ItemAdded, m_lsBindingList.Count - 1 ));
}
else
result = null ;
return result;
}
/// <summary>
/// 获取是否可更新列表中的项--实现IBindingList接口
/// </summary>
public bool AllowEdit
{
get
{
if (m_bSupportsBinding)
return m_lsBindingList.AllowEdit;
else
return false ;
}
}
/// <summary>
/// 获取是否可以使用 System.ComponentModel.IBindingList.AddNew() 向列表中添加项--实现IBindingList接口
/// </summary>
public bool AllowNew
{
get
{
if (m_bSupportsBinding)
return m_lsBindingList.AllowNew;
else
return false ;
}
}
/// <summary>
/// 获取是否可以使用 System.Collections.IList.Remove(System.Object) 或 System.Collections.IList.RemoveAt(System.Int32)
/// 从列表中移除项。--实现IBindingList接口
/// </summary>
public bool AllowRemove
{
get
{
if (m_bSupportsBinding)
return m_lsBindingList.AllowRemove;
else
return false ;
}
}
/// <summary>
/// 从用于搜索的索引中移除 System.ComponentModel.PropertyDescriptor--实现IBindingList接口
/// </summary>
/// <param name="property"></param>
public void RemoveIndex(PropertyDescriptor property)
{
if (m_bSupportsBinding)
m_lsBindingList.RemoveIndex(property);
}
public ListSortDirection SortDirection
{
get
{
return m_objOrderDirect;
}
}
public PropertyDescriptor SortProperty
{
get
{
return m_objSortByPro;
}
}
/// <summary>
/// 获取当列表更改或列表中的项更改时是否引发 System.ComponentModel.IBindingList.ListChanged 事件
/// </summary>
public bool SupportsChangeNotification
{
get
{
return true ;
}
}
public bool SupportsSearching
{
get
{
if (m_bSupportsBinding)
return m_lsBindingList.SupportsSearching;
else
return false ;
}
}
public bool SupportsSorting
{
get
{
return true ;
}
}
/// <summary>
/// 添加项
/// </summary>
/// <param name="item"></param>
public void Add(T item)
{
m_lsList.Add(item);
}
/// <summary>
/// 清空所有
/// </summary>
public void Clear()
{
m_lsList.Clear();
}
/// <summary>
/// 是否含有某项
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Contains(T item)
{
return m_lsList.Contains(item);
}
/// <summary>
/// 移除某项
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool Remove(T item)
{
return m_lsList.Remove(item);
}
/// <summary>
/// 是否只读
/// </summary>
public bool IsReadOnly
{
get
{
return m_lsList.IsReadOnly;
}
}
/// <summary>
/// 取得某项索引
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int IndexOf(T item)
{
return SortedIndex(m_lsList.IndexOf(item));
}
public void Insert( int index, T item)
{
m_lsList.Insert(index, item);
}
public T this [ int index]
{
get
{
if (m_bSorted)
return m_lsList[OriginalIndex(index)];
else
return m_lsList[index];
}
set
{
if (m_bSorted)
m_lsList[OriginalIndex(index)] = value;
else
m_lsList[index] = value;
}
}
int System.Collections.IList.IndexOf( object value)
{
return IndexOf((T)value);
}
void System.Collections.IList.Insert( int index, object value)
{
Insert(index, (T)value);
}
/// <summary>
/// 移除指定索引的项
/// </summary>
/// <param name="index"></param>
public void RemoveAt( int index)
{
if (m_bSorted)
{
m_bInitiatedLocally = true ;
int baseIndex = OriginalIndex(index);
m_lsList.RemoveAt(baseIndex);
if (m_lsList.Count != m_lstSortIndex.Count)
{
if (m_objOrderDirect == ListSortDirection.Ascending)
m_lstSortIndex.RemoveAt(index);
else
m_lstSortIndex.RemoveAt(m_lstSortIndex.Count - 1 - index);
foreach (ListItem item in m_lstSortIndex)
if (item.BaseIndex > baseIndex)
item.BaseIndex -= 1 ;
}
OnListChanged( new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
m_bInitiatedLocally = false ;
}
else
m_lsList.RemoveAt(index);
}
int System.Collections.IList.Add( object value)
{
Add((T)value);
return SortedIndex(m_lsList.Count - 1 );
}
bool System.Collections.IList.Contains( object value)
{
return Contains((T)value);
}
bool System.Collections.IList.IsFixedSize
{
get
{
return false ;
}
}
object System.Collections.IList. this [ int index]
{
get
{
return this [index];
}
set
{
this [index] = (T)value;
}
}
void System.Collections.IList.Remove( object value)
{
Remove((T)value);
}
#endregion
#region 取得List中的Item的位置
/// <summary>
/// 用排序后的位置取得未排序前的位置
/// </summary>
/// <param name="nSortedIndex"></param>
/// <returns></returns>
private int OriginalIndex( int nSortedIndex)
{
if (m_bSorted)
{
if (m_objOrderDirect == ListSortDirection.Ascending)
return m_lstSortIndex[nSortedIndex].BaseIndex;
else
return m_lstSortIndex[m_lstSortIndex.Count - 1 - nSortedIndex].BaseIndex;
}
else
return nSortedIndex;
}
/// <summary>
/// 用排序前的位置取得排序后的位置
/// </summary>
/// <param name="nOriginalIndex"></param>
/// <returns></returns>
private int SortedIndex( int nOriginalIndex)
{
int result = 0 ;
if (m_bSorted)
{
for ( int index = 0 ; index < m_lstSortIndex.Count; index ++ )
{
if (m_lstSortIndex[index].BaseIndex == nOriginalIndex)
{
result = index;
break ;
}
}
if (m_objOrderDirect == ListSortDirection.Descending)
result = m_lstSortIndex.Count - 1 - result;
}
else
result = nOriginalIndex;
return result;
}
#endregion
#region 排序/撤销排序
/// <summary>
/// 排序
/// </summary>
private void DoSort()
{
int index = 0 ;
m_lstSortIndex.Clear();
if (m_objSortByPro == null )
{
foreach (T obj in m_lsList)
{
m_lstSortIndex.Add( new ListItem(obj, index));
index ++ ;
}
}
else
{
foreach (T obj in m_lsList)
{
m_lstSortIndex.Add( new ListItem(m_objSortByPro.GetValue(obj), index));
index ++ ;
}
}
m_lstSortIndex.Sort();
m_bSorted = true ;
OnListChanged( new ListChangedEventArgs(ListChangedType.Reset, 0 ));
}
/// <summary>
/// 撤销排序
/// </summary>
private void UndoSort()
{
m_lstSortIndex.Clear();
m_objSortByPro = null ;
m_objOrderDirect = ListSortDirection.Ascending;
m_bSorted = false ;
OnListChanged( new ListChangedEventArgs(ListChangedType.Reset, 0 ));
}
#endregion
#region IEnumerable与IEnumerable<T> 成员
IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator < T > GetEnumerator()
{
if (m_bSorted)
return new SortedEnumerator(m_lsList, m_lstSortIndex, m_objOrderDirect);
else
return m_lsList.GetEnumerator();
}
#endregion
#region ICollection与ICollection<T> 成员
public int Count
{
get
{
return m_lsList.Count;
}
}
bool System.Collections.ICollection.IsSynchronized
{
get
{
return false ;
}
}
object System.Collections.ICollection.SyncRoot
{
get
{
return m_lsList;
}
}
public void CopyTo(T[] array, int arrayIndex)
{
m_lsList.CopyTo(array, arrayIndex);
}
void System.Collections.ICollection.CopyTo(System.Array array, int index)
{
CopyTo((T[])array, index);
}
#endregion
#region ICancelAddNew 成员
void ICancelAddNew.CancelNew( int itemIndex)
{
ICancelAddNew can = m_lsList as ICancelAddNew;
if (can != null )
can.CancelNew(itemIndex);
else
m_lsList.RemoveAt(itemIndex);
}
void ICancelAddNew.EndNew( int itemIndex)
{
ICancelAddNew can = m_lsList as ICancelAddNew;
if (can != null )
can.EndNew(itemIndex);
}
#endregion
#region SortedEnumerator 类
private class SortedEnumerator : IEnumerator < T >
{
private IList < T > m_list;
private List < ListItem > m_sortIndex;
private ListSortDirection m_sortOrder;
private int m_nIndex;
private bool _disposedValue = false ;
public SortedEnumerator(IList < T > list, List < ListItem > sortIndex, ListSortDirection direction)
{
m_list = list;
m_sortIndex = sortIndex;
m_sortOrder = direction;
Reset();
}
public T Current
{
get
{
return m_list[m_sortIndex[m_nIndex].BaseIndex];
}
}
Object System.Collections.IEnumerator.Current
{
get
{
return m_list[m_sortIndex[m_nIndex].BaseIndex];
}
}
public bool MoveNext()
{
if (m_sortOrder == ListSortDirection.Ascending)
{
if (m_nIndex < m_sortIndex.Count - 1 )
{
m_nIndex ++ ;
return true ;
}
else
return false ;
}
else
{
if (m_nIndex > 0 )
{
m_nIndex -- ;
return true ;
}
else
return false ;
}
}
public void Reset()
{
if (m_sortOrder == ListSortDirection.Ascending)
m_nIndex = - 1 ;
else
m_nIndex = m_sortIndex.Count;
}
#region IDisposable 实现
protected virtual void Dispose( bool disposing)
{
if ( ! _disposedValue)
{
if (disposing)
{
}
}
_disposedValue = true ;
}
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
~ SortedEnumerator()
{
Dispose( false );
}
#endregion
}
#endregion
#region ListItem 类
private class ListItem : IComparable < ListItem >
{
private object m_objKey;
private int m_nBaseIndex;
public object Key
{
get
{
return m_objKey;
}
}
public int BaseIndex
{
get
{
return m_nBaseIndex;
}
set
{
m_nBaseIndex = value;
}
}
public ListItem( object objKey, int nBaseIndex)
{
m_objKey = objKey;
m_nBaseIndex = nBaseIndex;
}
// 实现IComparable接口
public int CompareTo(ListItem other)
{
object target = other.Key;
if (Key is IComparable)
return ((IComparable)Key).CompareTo(target);
else
{
if (Key == null )
{
if (target == null )
return 0 ;
else
return - 1 ;
}
else if (Key.Equals(target))
return 0 ;
else
return Key.ToString().CompareTo(target.ToString());
}
}
public override string ToString()
{
return Key.ToString();
}
}
#endregion
}
}
使用 SortedBindingList<CashInCome> m_lsSort = new SortedBindingList<CashInCome>(dtBind);