首页 > 编程语言 >C# .net中PropertyDescriptor的使用和BindingList的ApplySort排序

C# .net中PropertyDescriptor的使用和BindingList的ApplySort排序

时间:2024-01-18 17:58:57浏览次数:42  
标签:C# ApplySort void PropertyDescriptor prop originalList tbNumber var

找了好多资料都是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
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

标签:C#,ApplySort,void,PropertyDescriptor,prop,originalList,tbNumber,var
From: https://www.cnblogs.com/bklsj/p/17973010

相关文章

  • instanceof和类型之间的转换
    publicclassApplication{  publicstaticvoidmain(String[]args){    //Object>String    //Object>Person>Student    //Object>Person>Teacher    //System.out.println(Xinstanceofy);能不能编译通过//   Objectobj......
  • C++基础
    一、理论      1、虚函数 1.1、定义:​虚函数就是在类中被关键字virtual声明的函数,一般只在基类中声明虚函数。    1.2、规则:                   1、虚函数必须是......
  • SM30里DEC数据显示0
    需求:DEC数据在维护的时候显示01,设置数据元素对于的域带转换历程、 2,写转换历程函数(注意两个历程的输入和输出类型,这个需要修改)FUNCTIONCONVERSION_EXIT_ZDAYS_INPUT.*"----------------------------------------------------------------------*"*"LocalInterface:*"......
  • CodeForces 1466H Finding satisfactory solutions
    洛谷传送门CF传送门考虑给定\(b\)如何构造\(a\)。拎出基环树的环部分,把这些点连同它们的边删掉(这个环一定在答案中)。递归做即可。考虑我们在\(a\)的环上连一些在\(\{b_{i,n}\}\)中排得比\(a_i\)前的\(i\toj\)。可以将问题转化为,若干个环,缩点后连一些边使得它成......
  • Linux中利用shell脚本提升cpu使用率
    使用背景:因新申请下来的服务器暂时没有部署任何应用导致cpu使用率很低,那资源组那边给出两个方案,1.要不把服务器用起来2服务器进行降配降配是不可能降配的,后面正式用起来去升配就很麻烦了使用说明:这个脚本主要是针对多核服务器进行使用,前提你想让你服务器......
  • ubuntu安装最新版的xtrabackup
    官方文档:https://www.percona.com/doc/percona-xtrabackup/8.0/installation/apt_repo.html1,首先都在root用户下操作,不然提示权限不足wgethttps://repo.percona.com/apt/percona-release_latest.$(lsb_release-sc)_all.deb通过上面命令得到最新的安装包,会根据你的系统来,......
  • MFC 自定义控件添加 tip
    一、要求1.自定义tip提示并实时提示,跟随鼠标移动2.避免重复刷导致tip闪烁3.picture控件添加自定义变量二、tip涉及2.1CMFCToolTipCtrl、CMFCToolTipInfoCMFCToolTipCtrl*m_ptooltip;//注册控件、传递提示消息CMFCToolTipInfo*m_ttinfo;//样式处理......
  • Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
    大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.to_excel之前把这一列转换成字符串,或者你在Excel上设置......
  • jmeter使用jdbc连接SQL server,执行SQL报错处理
    前置环境参数:jdk-8u391-windows-x64,驱动:sqljdbc4.jar备注:这是解决后的截图,将就用问题一:使用jmeter5.5,使用jdbc连接SQLserver,执行SQL报错处理,如下图 报错信息:java.lang.UnsupportedClassVersionError:com/microsoft/sqlserver/jdbc/SQLServerDriverhasbeencompiledby......
  • exit配置iscis卷
    一、在NAS上创建一个iscis卷 二、登录exit主机---存储-----软件ISCSI三、添加动态目标输入NAS的ISCIS盘和CHAP身份验证 四、重新扫描一下,进入设备------可以看到我们添加进来的ISCIS设备五、选择要添加的虚拟机--------编辑--------添加裸盘 ......