代码改变世界

解决DataGridView绑定List后不能排序的问题

  苏飞  阅读(13024)  评论(12编辑  收藏  举报

   阅读全文并下载例子 :http://www.sufeinet.com/forum.php?mod=viewthread&tid=190

  以前不都是用table直接绑定DataGridView的,没有出现过不能排序的问题,初试List结果发现不管怎么样都不能实现排序的功能,有朋友说

DataGridView每一列都有个Sortable,默认Automatic,改成NotSortable了,结果怎样,还是不行啦。

     还有朋友说, 你可以拖一个bindingsource控件. bindingsource.datasource=泛型集合 datagridview.datasource=bindingsource;

我发现也是不行,那要怎么办呢?查一下资料才知道

    用泛型会失去DateTable的特性,要实现System.Collections.Generic.IComparer<T> 才能实现排序

 没有办法只能实现 一把了

  看一下下面的代码吧, 基本 是这样的

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

namespace BaseFunction
{
    
class ObjectPropertyCompare<T> : System.Collections.Generic.IComparer<T> 
    {
        
private PropertyDescriptor property;
        
private ListSortDirection direction;

        
public ObjectPropertyCompare(PropertyDescriptor property, ListSortDirection direction)
        {
            
this.property = property;
            
this.direction = direction;
        }

        
#region IComparer<T>

        
/// <summary>
        
/// 比较方法
        
/// </summary>
        
/// <param name="x">相对属性x</param>
        
/// <param name="y">相对属性y</param>
        
/// <returns></returns>
        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;
            }
        }

        
public bool Equals(T xWord, T yWord)
        {
            
return xWord.Equals(yWord);
        }

        
public int GetHashCode(T obj)
        {
            
return obj.GetHashCode();
        }

        
#endregion
    }
}

复制代码

 

在实现了这个接口之后还不能急,我们还要来写一个SortableBindingList <T> :BindingList <T> 的类用来绑定数据

基本实现

 

复制代码
代码
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace BaseFunction
{
    
public class BindingCollection<T> : BindingList<T>
    {
        
private bool isSorted;
        
private PropertyDescriptor sortProperty;
        
private ListSortDirection sortDirection;

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

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

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

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

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

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

        
protected override void RemoveSortCore()
        {
            isSorted 
= false;
            
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }
        //排序
        
public void Sort(PropertyDescriptor property, ListSortDirection direction)
        {
            
this.ApplySortCore(property, direction);
        }
    }
}
复制代码

 

现 在应该流到怎么使用了,其实很简单

直接

 BindingCollection<object > objList = new BindingCollection<object>();
 objList 
=你的结果集;
 
this.dataGridView1.DataSource = objList;

 

但是现在是问题是我的之前用的是List,不想改,而且调用的是Dll,人家返回的就是一个List,我没有办法改成BindingCollection<object >啊。

想了半天还是想出来了,只是不知道 在性能和别的方面怎么样,所以把代码发上来大家讨论一下

我是这样实现 的

复制代码
代码
 //可以实现排序的类
            BindingCollection<historyorderInfo> objList = new BindingCollection<historyorderInfo>();
            
//加载数据
            foreach (historyorderInfo item in tmpList)
            {
                objList.Add(item);
            }
            dgvhistory.DataSource 
= objList;
复制代码

 

 

这里的tmpList就是我之前使用的系统原本的List,我是使用了 foreach 把原来的数据导入到BindingCollection中的。

这样的确定是可以实现 我想要的效果的。不知道这样做有什么不到之处。希望能得到高人的指点啊,呵呵

 

(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示