排序类.不管什么类型都能排
代码
using System;
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
}
}
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);