Winform中DataGridView绑定List<T>数据源时,点击DataGridView列头不能自动排序解决方法

*********************************************方法一*********************************************

自定义集体类:

复制代码
using  System.ComponentModel;
using  System.Collections.Generic;
using  System.Reflection;
using  System;

public   class  SortableBindingList < T >  : BindingList < T >
{
    
private   bool  isSortedCore  =   true ;
    
private  ListSortDirection sortDirectionCore  =  ListSortDirection.Ascending;
    
private  PropertyDescriptor sortPropertyCore  =   null ;
    
private   string  defaultSortItem;

    
public  SortableBindingList() :  base () { }

    
public  SortableBindingList(IList < T >  list) :  base (list) { }

    
protected   override   bool  SupportsSortingCore
    {
        
get  {  return   true ; }
    }

    
protected   override   bool  SupportsSearchingCore
    {
        
get  {  return   true ; }
    }

    
protected   override   bool  IsSortedCore
    {
        
get  {  return  isSortedCore; }
    }

    
protected   override  ListSortDirection SortDirectionCore
    {
        
get  {  return  sortDirectionCore; }
    }

    
protected   override  PropertyDescriptor SortPropertyCore
    {
        
get  {  return  sortPropertyCore; }
    }

    
protected   override   int  FindCore(PropertyDescriptor prop,  object  key)
    {
        
for  ( int  i  =   0 ; i  <   this .Count; i ++ )
        {
            
if  (Equals(prop.GetValue( this ), key))  return  i;
        }
        
return   - 1 ;
    }

    
protected   override   void  ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
    {
        isSortedCore 
=   true ;
        sortPropertyCore 
=  prop;
        sortDirectionCore 
=  direction;
        Sort();
    }

    
protected   override   void  RemoveSortCore()
    {
        
if  (isSortedCore)
        {
            isSortedCore 
=   false ;
            sortPropertyCore 
=   null ;
            sortDirectionCore 
=  ListSortDirection.Ascending;
            Sort();
        }
    }

    
public   string  DefaultSortItem
    {
        
get  {  return  defaultSortItem; }
        
set
        {
            
if  (defaultSortItem  !=  value)
            {
                defaultSortItem 
=  value;
                Sort();
            }
        }
    }

    
private   void  Sort()
    {
        List
< T >  list  =  ( this .Items  as  List < T > );
        list.Sort(CompareCore);
        ResetBindings();
    }

    
private   int  CompareCore(T o1, T o2)
    {
        
int  ret  =   0 ;
        
if  (SortPropertyCore  !=   null )
        {
            ret 
=  CompareValue(SortPropertyCore.GetValue(o1), SortPropertyCore.GetValue(o2), SortPropertyCore.PropertyType);
        }
        
if  (ret  ==   0   &&  DefaultSortItem  !=   null )
        {
            PropertyInfo property 
=   typeof (T).GetProperty(DefaultSortItem, BindingFlags.Public  |  BindingFlags.GetProperty  |  BindingFlags.Instance  |  BindingFlags.IgnoreCase,  null null new  Type[ 0 ],  null );
            
if  (property  !=   null )
            {
                ret 
=  CompareValue(property.GetValue(o1,  null ), property.GetValue(o2,  null ), property.PropertyType);
            }
        }
        
if  (SortDirectionCore  ==  ListSortDirection.Descending) ret  =   - ret;
        
return  ret;
    }

    
private   static   int  CompareValue( object  o1,  object  o2, Type type)
    {
        
// 这里改成自己定义的比较 
         if  (o1  ==   null return  o2  ==   null   ?   0  :  - 1 ;
        
else   if  (o2  ==   null return   1 ;
        
else   if  (type.IsPrimitive  ||  type.IsEnum)  return  Convert.ToDouble(o1).CompareTo(Convert.ToDouble(o2));
        
else   if  (type  ==   typeof (DateTime))  return  Convert.ToDateTime(o1).CompareTo(o2);
        
else   return  String.Compare(o1.ToString().Trim(), o2.ToString().Trim());
    }
}
复制代码

 



****************************************************************************方法二*************************************************************************************

首先,实现ICompare接口

复制代码
public   class  ObjectPropertyCompare < T >  : IComparer < T >  {
private  PropertyDescriptor property;
private  ListSortDirection direction;

//  构造函数
public  ObjectPropertyCompare(PropertyDescriptor property, ListSortDirection direction) {
this .property  =  property;
this .direction  =  direction;
}

//  实现IComparer中方法
public   int  Compare(T x, T y) {
object  xValue  =  x.GetType().GetProperty(property.Name).GetValue(x,  null );
object  yValue  =  y.GetType().GetProperty(property.Name).GetValue(y,  null );

int  returnValue;

if  (xValue  is  IComparable) {
returnValue 
=  ((IComparable)xValue).CompareTo(yValue);
else   if  (xValue.Equals(yValue)) {
returnValue 
=   0 ;
else  {
returnValue 
=  xValue.ToString().CompareTo(yValue.ToString());
}

if  (direction  ==  ListSortDirection.Ascending) {
return  returnValue;
else  {
return  returnValue  *   - 1 ;
}
}
}
复制代码

然后创建自定义的类,实现IBindingList接口,为方便起见,这里直接继承BindingList类

复制代码
///   <summary>
///  自定义绑定列表类
///   </summary>
///   <typeparam name="T"> 列表对象类型 </typeparam>
public   class  BindingCollection < T >  : BindingList < T >  {
private   bool  isSorted;
private  PropertyDescriptor sortProperty;
private  ListSortDirection sortDirection;

///   <summary>
///  构造函数
///   </summary>
public  BindingCollection()
base () {
}

///   <summary>
///  构造函数
///   </summary>
///   <param name="list"> IList类型的列表对象 </param>
public  BindingCollection(IList < T >  list)
base (list) {
}

///   <summary>
///  自定义排序操作
///   </summary>
///   <param name="property"></param>
///   <param name="direction"></param>
protected   override   void  ApplySortCore(PropertyDescriptor property, ListSortDirection direction) {
List
< T >  items  =   this .Items  as  List < T > ;

if  (items  !=   null ) {
ObjectPropertyCompare
< T >  pc  =   new  ObjectPropertyCompare < T > (property, direction);
items.Sort(pc);
isSorted 
=   true ;
else  {
isSorted 
=   false ;
}

sortProperty 
=  property;
sortDirection 
=  direction;

this .OnListChanged( new  ListChangedEventArgs(ListChangedType.Reset,  - 1 ));
}

///   <summary>
///  获取一个值,指示列表是否已排序
///   </summary>
protected   override   bool  IsSortedCore {
get  {
return  isSorted;
}
}

///   <summary>
///  获取一个值,指示列表是否支持排序
///   </summary>
protected   override   bool  SupportsSortingCore {
get  {
return   true ;
}
}

///   <summary>
///  获取一个只,指定类别排序方向
///   </summary>
protected   override  ListSortDirection SortDirectionCore {
get  {
return  sortDirection;
}
}

///   <summary>
///  获取排序属性说明符
///   </summary>
protected   override  PropertyDescriptor SortPropertyCore {
get  {
return  sortProperty;
}
}

///   <summary>
///  移除默认实现的排序
///   </summary>
protected   override   void  RemoveSortCore() {
isSorted 
=   false ;
this .OnListChanged( new  ListChangedEventArgs(ListChangedType.Reset,  - 1 ));
}
复制代码


原来的方式是:

IList<object> list = new List<object>();

...

dataGridView.DataSource = list;

现在只需更改最后一句为:

dataGridView.DataSource = new BindingCollection<object>(list);

即可


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值