找了好多资料都是java中PropertyDescriptor的使用,至于C#中的都抄袭别人的,又讲不清楚怎么用。官方文档也没不会手把手教你怎么用,经过一下午的研究,结果如下
1、找到PropertyDescriptor同一dll下的,使用TypeDescriptor反射出属性的PropertyDescriptorCollection ,从这里拿出对应属性的PropertyDescriptor
var myAttribute = TypeDescriptor.GetProperties(_tbNumber)[nameof(_tbNumber.SerialNumber)];
2、就可以使用ApplySort方法了
((IBindingList)listTable).ApplySort(myAttribute,ListSortDirection.Descending);
但是
但是
但是
运行结果报错。也不知道微软是用PropertyDescriptor的哪个属性,我猜测过是使用了Descriptor特性,设置model中的Descriptor也无效。
[Description(nameof(SerialNumber))] public int SerialNumber { get; set; }
然后查询资料得知了重要的一点,BindList的属性SortPropertyCore默认不开启排序。需要派生类自行实现(我tm出口成小说“¥%……#@&@"省略一万字)
从网上找了实现代码,经过测试修改,如下(来自某论坛2008年的代码),麻烦帮忙艾特下微软把代码加进去:
public class MySortableBindingList<T> : BindingList<T> { // reference to the list provided at the time of instantiation List<T> originalList; ListSortDirection sortDirection; PropertyDescriptor sortProperty; // function that refereshes the contents // of the base classes collection of elements Action<MySortableBindingList<T>, List<T>> populateBaseList = (a, b) => a.ResetItems(b); // a cache of functions that perform the sorting // for a given type, property, and sort direction static Dictionary<string, Func<List<T>, IEnumerable<T>>> cachedOrderByExpressions = new Dictionary<string, Func<List<T>, IEnumerable<T>>>(); public MySortableBindingList(){ originalList = new List<T>(); } public MySortableBindingList(IEnumerable<T> enumerable) { originalList = enumerable.ToList(); populateBaseList(this, originalList); } public MySortableBindingList(List<T> list) { originalList = list; populateBaseList(this, originalList); } protected override void ApplySortCore(PropertyDescriptor prop,ListSortDirection direction) { /* Look for an appropriate sort method in the cache if not found . Call CreateOrderByMethod to create one. Apply it to the original list. Notify any bound controls that the sort has been applied. */ sortProperty = prop; sortDirection = direction; var orderByMethodName = sortDirection == ListSortDirection.Ascending ? "OrderBy" : "OrderByDescending"; var cacheKey = typeof(T).GUID + prop.Name + orderByMethodName; if (!cachedOrderByExpressions.ContainsKey(cacheKey)) { CreateOrderByMethod(prop, orderByMethodName, cacheKey); } ResetItems(cachedOrderByExpressions[cacheKey](originalList).ToList()); ResetBindings(); } private void CreateOrderByMethod(PropertyDescriptor prop, string orderByMethodName, string cacheKey) { /* Create a generic method implementation for IEnumerable<T>. Cache it. */ var sourceParameter = Expression.Parameter(typeof(List<T>), "source"); var lambdaParameter = Expression.Parameter(typeof(T), "lambdaParameter"); var accesedMember = typeof(T).GetProperty(prop.Name); var propertySelectorLambda = Expression.Lambda(Expression.MakeMemberAccess(lambdaParameter, accesedMember), lambdaParameter); var orderByMethod = typeof(Enumerable).GetMethods() .Where(a => a.Name == orderByMethodName &&a.GetParameters().Length == 2) .Single() .MakeGenericMethod(typeof(T), prop.PropertyType); var orderByExpression = Expression.Lambda<Func<List<T>, IEnumerable<T>>>( Expression.Call(orderByMethod, new Expression[] { sourceParameter, propertySelectorLambda }), sourceParameter); cachedOrderByExpressions.Add(cacheKey, orderByExpression.Compile()); } protected override void RemoveSortCore()=> ResetItems(originalList); private void ResetItems(List<T> items) { base.ClearItems(); for (int i = 0; i < items.Count; i++) { base.InsertItem(i, items[i]); } } protected override bool SupportsSortingCore => true; protected override ListSortDirection SortDirectionCore => sortDirection; protected override PropertyDescriptor SortPropertyCore => sortProperty; protected override void OnListChanged(ListChangedEventArgs e) { originalList = base.Items.ToList(); base.OnListChanged(e); } }
使用
MySortableBindingList<tbNumber> listTable = new MySortableBindingList<tbNumber>(); private void Main_Load(object sender, EventArgs e) { dgv.DataSource = listTable; } private bool? added(tbNumber _tbNumber) { if (listTable.Count > 20) { TipCommon.ShowInfoTip("A maximum of 20 can be added"); return false; } int c = listTable.Count(a => a.SerialNumber == _tbNumber.SerialNumber); if (c > 0) { TipCommon.ShowInfoTip("This serial number already exists."); return false; } listTable.Add(_tbNumber); var myAttribute = TypeDescriptor.GetProperties(_tbNumber)[nameof(_tbNumber.SerialNumber)]; ((IBindingList)listTable).ApplySort(myAttribute,ListSortDirection.Descending); return true; } private void btnAdd_Click(object sender, EventArgs e) { frmNumberForm _frmNumberForm = new frmNumberForm(); _frmNumberForm.added += added; _frmNumberForm.ShowDialog(); }
作者:兮去博客
出处:https://www.cnblogs.com/bklsj/p/17973010
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任