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;
}
}