using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading.Tasks; /// /// 一个更高性能的用于数据绑定的对象,继承自BindingList对象 /// 添加了AddRange、InsertRange,支持批量添加后再整体刷新视图,提高性能 /// 添加了几个常用的类似Linq中List的函数 /// 该对象可直接用于json序列化和反序列化,其结果和List一样 /// /// 泛型对象 /// BindingData不具有线程安全特性,该对象应该只初始化一次,通过Clear、Add等更新 public class BindingData : BindingList where T : class, new() { public event Action OnItemDelete; public BindingData() : base() { } /// /// 是否支持排序 /// protected override bool SupportsSortingCore { get { return true; } } /// /// 是否支持搜索 /// protected override bool SupportsSearchingCore { get { return true; } } protected override void RemoveItem(int itemIndex) { OnItemDelete?.Invoke(this[itemIndex]); base.RemoveItem(itemIndex); } public BindingData(IEnumerable data) { //构造函数中不会触发OnListChanged this.AddRange(data); } public void AddRange(IEnumerable items) { if (items == null || items.Count() == 0) return; RaiseListChangedEvents = false;//让View不刷新 foreach (var item in items) { Add(item); } OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0));//批量更新View RaiseListChangedEvents = true;//让View继续更新 } public void InsertRange(IEnumerable items) { if (items == null || items.Count() == 0) return; RaiseListChangedEvents = false;//让View不刷新 int count = items.Count(); for (int i = count - 1; i >= 0; i--) { InsertItem(0, items.ElementAt(i)); } OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0));//批量更新View RaiseListChangedEvents = true;//让View继续更新 } public T[] GetRows(int[] rows) { if (this.Count < 0) return null; List list = new List(); foreach (var index in rows) { if (index < 0 || index >= this.Count) continue; list.Add(this[index]); } return list.ToArray(); } public int RemoveAll(Predicate match) { var list = this.FindAll(match); RaiseListChangedEvents = false;//让View不刷新 int i = 0; foreach (var item in list) { if (this.Remove(item)) i++; } OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, 0));//批量更新View RaiseListChangedEvents = true;//让View继续更新 return i; } public void RemoveAll(T[] data) { foreach (var item in data) { this.Remove(item); } } public T Find(Predicate match) { foreach (var item in this) { if (match(item)) return item; } return default; } public List FindAll(Predicate match) { List list = new List(); foreach (var item in this) { if (match(item)) list.Add(item); } return list; } public int FindIndex(Predicate match) { int idx = 0; foreach (var item in this) { if (match(item)) return idx; idx++; } return -1; } public bool Exists(Predicate match) { foreach (var item in this) { if (match(item)) return true; } return false; } public void SortData(Expression> express, bool asc = true) { RaiseListChangedEvents = false;//让View不刷新 List tmp; if (asc) tmp = this.OrderBy(express.Compile()).ToList(); else tmp = this.OrderByDescending(express.Compile()).ToList(); this.Clear(); this.AddRange(tmp); RaiseListChangedEvents = true;//让View继续更新 } public List DeepClone() { ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "p"); List memberBindingList = new List(); foreach (var item in typeof(T).GetProperties()) { if (!item.CanWrite) continue; MemberExpression property = Expression.Property(parameterExpression, typeof(T).GetProperty(item.Name)); MemberBinding memberBinding = Expression.Bind(item, property); memberBindingList.Add(memberBinding); } MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(T)), memberBindingList.ToArray()); Expression> lambda = Expression.Lambda>(memberInitExpression, new ParameterExpression[] { parameterExpression }); List list = new List(); foreach (var item in this) { list.Add(lambda.Compile()(item)); } return list; } }