http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 13401|回复: 1

[Winform] 解决“DataGridView 控件必须绑定到 IBindingList 对象才能排序”的问题

[复制链接]
发表于 2012-7-29 07:03:37 | 显示全部楼层 |阅读模式
以前不都是用table直接绑定DataGridView的,没有出现过不能排序的问题,初试List结果发现不管怎么样都不能实现排序的功能,有朋友说DataGridView每一列都有个Sortable,默认Automatic,改成NotSortable了,结果怎样,还是不行啦。
还有朋友说, 你可以拖一个bindingsource控件. bindingsource.datasource=泛型集合 datagridview.datasource=bindingsource;
我发现也是不行,那要怎么办呢?查一下资料才知道
用泛型会失去DateTable的特性,要实现System.Collections.Generic.IComparer<T> 才能实现排序
没有办法只能实现 一把了
看一下下面的代码吧, 基本 是这样的
[C#] 纯文本查看 复制代码
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> 的类用来绑定数据
基本实现
[C#] 纯文本查看 复制代码
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);
        }
    }
}


现 在应该流到怎么使用了,其实很简单
直接
[C#] 纯文本查看 复制代码
BindingCollection<object > objList = new BindingCollection<object>();
 objList =你的结果集;
 this.dataGridView1.DataSource = objList;

但是现在是问题是我的之前用的是List,不想改,而且调用的是Dll,人家返回的就是一个List,我没有办法改成BindingCollection<object >啊。
想了半天还是想出来了,只是不知道 在性能和别的方面怎么样,所以把代码发上来大家讨论一下
我是这样实现 的
[C#] 纯文本查看 复制代码
//可以实现排序的类
            BindingCollection<historyorderInfo> objList = new BindingCollection<historyorderInfo>();
            //加载数据
            foreach (historyorderInfo item in tmpList)
            {
                objList.Add(item);
            }
            dgvhistory.DataSource = objList;

这里的tmpList就是我之前使用的系统原本的List,我是使用了 foreach 把原来的数据导入到BindingCollection中的。
这样的确定是可以实现 我想要的效果的。不知道这样做有什么不到之处。希望能得到高人的指点啊,呵呵



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2013-8-20 17:31:27 | 显示全部楼层
  dgvhistory.DataSource = objList.AsBindingCollection(); 把转换的地方封装在AsBindingCollection里面,AsBindingCollection可以认为是一个拓展方法。。
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-6-14 05:03

© 2014-2021

快速回复 返回顶部 返回列表