using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Diagnostics; namespace ChuPiao.Common.Utils { /// <summary> /// 用于读取大数据的列表 /// </summary> public class VirtualList<T> : ObservableCollection<T>, IList, IList<T> { #region IList 成员 public int Add(object value) { throw new NotImplementedException(); } public new void Clear() { throw new NotImplementedException(); } public bool Contains(object value) { throw new NotImplementedException(); } public int IndexOf(object value) { throw new NotImplementedException(); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { throw new NotImplementedException(); } } public new bool IsReadOnly { get { return true; } } public void Remove(object value) { throw new NotImplementedException(); } public new void RemoveAt(int index) { throw new NotImplementedException(); } public new object this[int index] { get { return ((IList<T>)this)[index]; } set { throw new NotImplementedException(); } } #endregion #region ICollection 成员 public void CopyTo(Array array, int index) { throw new NotImplementedException(); } private int _count = -1; public new int Count { get { if (-1 == _count) { if (null != OnQueryCount) { _count = OnQueryCount(); } } return _count == -1 ? 0 : _count; } } /// <summary> /// 需要查询列表总数时发生 /// </summary> public event OnQueryCountDelegate OnQueryCount; public delegate int OnQueryCountDelegate(); public bool IsSynchronized { get { return false; } } public object SyncRoot { get { return this; } } #endregion #region IEnumerable 成员 public IEnumerator GetEnumerator() { throw new NotImplementedException(); } #endregion #region IList<T> 成员 public new int IndexOf(T item) { throw new NotImplementedException(); } public new void Insert(int index, T item) { throw new NotImplementedException(); } /// <summary> /// 从虚拟表中根据Index查找项 /// </summary> /// <param name="index"></param> /// <returns></returns> T IList<T>.this[int index] { get { //如果没有数据就直接返回默认项目 if (0 == this.Count) { return default(T); } //如果数据在cache中则返回数据 if (_headIndex <= index && index < _headIndex + _cachedItems.Count) { return _cachedItems[index - _headIndex]; } //否则就读取数据 else { //计算开始读取的位置 int headIndex = 0; int radius = _fetchSize / 2; //如果viewPoint到数据开始位置的距离小于半径,那么就从开始位置读取数据 if ((index - radius) < 0) { headIndex = 0; } //如果viewPoint离最后一条数据的位置小于半径,那么就从最后一条数据开始向上fetchSize的位置开始读取数据 else if ((index + radius) > _count) { headIndex = _count - _fetchSize; //如果开始位置超过了起始位置,那么还要从起始位置开始读取数据 if (headIndex < 0) { headIndex = 0; } } //如果viewPoint的上下半径范围都没有超过队首或者队尾,那么取数据的开始位置在index-radius的位置 else { headIndex = index - radius; } if (null != OnQueryPage) { _cachedItems = OnQueryPage(headIndex, _fetchSize); } else { throw new Exception("需要获取数据的方法"); } _headIndex = headIndex; _tailIndex = headIndex + _cachedItems.Count - 1; return ((IList<T>)this)[index]; } } set { throw new NotImplementedException(); } } /// <summary> /// 在内存中的数据 /// </summary> private List<T> _cachedItems = new List<T>(); /// <summary> /// 当需要从数据库中查询数据时发生 /// 两个传入参数: /// 1.查询的起始位置 /// 2.需要查询的条数 /// 返回:符合条件的结果列表 /// /// </summary> public event Func<int, int, List<T>> OnQueryPage; #endregion #region ICollection<T> 成员 public new void Add(T item) { throw new NotImplementedException(); } /// <summary> ///被依赖的服务 /// </summary> private string[] _byDepended; public string[] ByDepended { get { return _byDepended; } set { _byDepended=value; } } /// <summary> /// 依赖服务 /// </summary> private string[] _depend; public string[] Depend { get { return _depend; } set { _depend = value; } } new bool Contains(T item) { throw new NotImplementedException(); } public new void CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); } public new bool Remove(T item) { throw new NotImplementedException(); } #endregion #region IEnumerable<T> 成员 IEnumerator<T> IEnumerable<T>.GetEnumerator() { throw new NotImplementedException(); } #endregion /// <summary> /// 缓存中第一条数据对应的位置 /// </summary> private int _headIndex = -1; /// <summary> /// 缓存中最后一条数据对应的位置 /// </summary> private int _tailIndex = -1; private int _fetchSize = 100; /// <summary> /// 设置或获取每次获取数据的条数 /// </summary> public int FetchSize { get { return _fetchSize; } set { _fetchSize = value; } } /// <summary> /// 复位列表 /// </summary> public void Reset() { _headIndex = -1; _count = -1; _cachedItems.Clear(); NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset); OnCollectionChanged(args); } } }