winform datagridview 绑定泛型集合变得不支持排序的解决方案

案例:

  环境:Winform程序

  控件:Datagridview

  现象:Datagridview控件绑定到List<T>泛型数据上不支持排序

     Datagridview控件绑定到DataTable上可以支持排序

  结论:泛型会使Datagridview失去排序特性

  解决:实现BindingList<T>接口

  实现代码:

  

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Linq;
  5 using System.Reflection;
  6 using System.Text;
  7
  8 namespace HOET.Plugins.Orders.Model
  9 {
 10     /// <summary>
 11     /// 泛型会失去DataTable特性,DataGridView绑定List<T>后不支持排序
 12     /// </summary>
 13     /// <typeparam name="T"></typeparam>
 14     class SortableBindingList<T> : BindingList<T>
 15     {
 16         private bool isSortedCore = true;
 17         private ListSortDirection sortDirectionCore = ListSortDirection.Ascending;
 18         private PropertyDescriptor sortPropertyCore = null;
 19         private string defaultSortItem;
 20
 21         public SortableBindingList() : base() { }
 22
 23         public SortableBindingList(IList<T> list) : base(list) { }
 24
 25         protected override bool SupportsSortingCore
 26         {
 27             get { return true; }
 28         }
 29
 30         protected override bool SupportsSearchingCore
 31         {
 32             get { return true; }
 33         }
 34
 35         protected override bool IsSortedCore
 36         {
 37             get { return isSortedCore; }
 38         }
 39
 40         protected override ListSortDirection SortDirectionCore
 41         {
 42             get { return sortDirectionCore; }
 43         }
 44
 45         protected override PropertyDescriptor SortPropertyCore
 46         {
 47             get { return sortPropertyCore; }
 48         }
 49
 50         protected override int FindCore(PropertyDescriptor prop, object key)
 51         {
 52             for(int i = 0; i < this.Count; i++)
 53             {
 54                 if(Equals(prop.GetValue(this[i]),key))
 55                 {
 56                     return i;
 57                 }
 58             }
 59
 60             return -1;
 61         }
 62
 63         protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
 64         {
 65             isSortedCore = true;
 66             sortPropertyCore = prop;
 67             sortDirectionCore = direction;
 68             Sort();
 69         }
 70
 71         protected override void RemoveSortCore()
 72         {
 73             if(isSortedCore)
 74             {
 75                 isSortedCore = false;
 76                 sortPropertyCore = null;
 77                 sortDirectionCore = ListSortDirection.Ascending;
 78                 Sort();
 79             }
 80         }
 81
 82         public string DefaultSortItem
 83         {
 84             get
 85             {
 86                 return defaultSortItem;
 87             }
 88             set
 89             {
 90                 if(defaultSortItem != value)
 91                 {
 92                     defaultSortItem = value;
 93                     Sort();
 94                 }
 95             }
 96         }
 97
 98         private void Sort()
 99         {
100             List<T> list = this.Items as List<T>;
101             list.Sort(CompareCore);
102             ResetBindings();
103         }
104
105         private int CompareCore(T o1, T o2)
106         {
107             int ret = 0;
108             if(SortPropertyCore != null)
109             {
110                 ret = CompareValue(SortPropertyCore.GetValue(o1), SortPropertyCore.GetValue(o2), SortPropertyCore.PropertyType);
111             }
112             if(ret == 0 && DefaultSortItem != null)
113             {
114                 PropertyInfo property = typeof(T).GetProperty(DefaultSortItem, BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.IgnoreCase, null, null, new Type[0], null);
115                 if(property != null)
116                 {
117                     ret = CompareValue(property.GetValue(o1, null), property.GetValue(o2, null), property.PropertyType);
118                 }
119             }
120             if(SortDirectionCore == ListSortDirection.Descending)
121             {
122                 ret = -ret;
123             }
124
125             return ret;
126         }
127
128         private static int CompareValue(object o1, object o2, Type type)
129         {
130             if(o1 == null)
131             {
132                 return o2 == null ? 0 : -1;
133             }
134             else if(o2 == null)
135             {
136                 return 1;
137             }
138             else if(type == typeof(char))
139             {
140                 return String.Compare(o1.ToString().Trim(), o2.ToString().Trim());
141             }
142             else if (type.IsEnum ||type.IsPrimitive)
143             {
144                 return Convert.ToDouble(o1).CompareTo(Convert.ToDouble(o2));
145             }
146             else if(type == typeof(DateTime))
147             {
148                 return Convert.ToDateTime(o1).CompareTo(o2);
149             }
150             else
151             {
152                 return String.Compare(o1.ToString().Trim(), o2.ToString().Trim());
153             }
154         }
155     }
156 }

  

时间: 2024-08-27 15:54:30

winform datagridview 绑定泛型集合变得不支持排序的解决方案的相关文章

[转]WinForm DataGridView 绑定泛型List(List&lt;T&gt;)/ArrayList不显示的原因和解决

背景:无意间遇到了一个不大不小的问题,希望对一些遇到的人有所帮助! 一.问题 WinForm DataGridView 绑定泛型List (List<T>)/ArrayList不显示,UI 代码如下: using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.IO; using System.Windows.Forms; namespace W

WinForm DataGridView 绑定泛型List(List&lt;T&gt;)/ArrayList不显示的原因和解决

背景:无意间遇到了一个不大不小的问题,希望对一些遇到的人有所帮助! 一.问题 WinForm DataGridView 绑定泛型List (List<T>)/ArrayList不显示,UI 代码如下: using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.IO; using System.Windows.Forms; namespace W

[WinForm] DataGridView绑定DataTable,ComboBox列绑定Dictionary

一  需求介绍 一般像枚举类型的数据,我们在数据库里存储着诸如(1.2.3.4-)或者("001"."002"."003"-)此类,但是界面上我们想要显示的是具体的文本内容,以便用户理解使用.所以在从数据库中加载出来的数据DataTable绑定到DataGridView上时,就需要其中一些枚举列采用下拉框,并绑定对应的枚举数据源. 二  具体实现 首先,如果 DataGridView 的 AutoGenerateColumns 为 true 时,

DataGridview 绑定泛型List&lt;T&gt;

1.DataGridView数据绑定对比(DataTable与泛型List): 当DataGridView的DataSource是DataTable的时候,DataTable的数据改变时,DataGridView的数据会随之改变,无需重新绑定到DataGridView. 当DataGridView的DataSource是泛型List,当List的数据改变时,则需要先将DataGridView的DataSource设置为new List<T>(),再将改变后的List<T>赋给Dat

[转]DataGridView绑定泛型List的种种

1.DataGridView数据绑定对比(DataTable与泛型List):当DataGridView的DataSource是DataTable的时候,DataTable的数据改变时,DataGridView的数据会随之改变,无需重新绑定到DataGridView.当DataGridView的DataSource是泛型List,当List的数据改变时,则需要先将DataGridView的DataSource设置为new List<T>(),再将改变后的List<T>赋给DataG

DataGridView 绑定list类, 如何只显示list集合中类的部分属性

一,显示实体的全部属性 当DataGridView的列名就是Class T的属性的时候,这时,只需要绑定数据源,然后手动更改列名就好. <span style="font-size:14px;"> '将dt转换为泛型集合 myList = EntityHelper.convertToList(Of EntityUser)(dt) TextBox1.Text = myList.Count '在文本框里面显示出查询到的教师数目 If (myList.Count > 0)

[Winform] DataGridView(FAQ)

Q1.  如何使单元格不可编辑? A:设置ReadOnly属性,可以设置的对象包括DataGridViewRow(行).DataGridViewColumn(列).DataGridViewCell(单元格)以及自身DataGridView对象均可设置ReadOnly属性来限制单元格的编辑状态. 扩展:需要注意的是,当DataGridView通过DataSource绑定数据自动生成行列时,如果直接在Form的构造函数初始化界面InitializeComponent后直接设置ReadOnly属性,会

C# winform dataGridView

1 private void btnConn_Click(object sender, EventArgs e) 2 { 3 //定义连接字符串 4 string constr = "server=.;database=DBTest;uid=sa;pwd=sa;"; 5 SqlConnection con = new SqlConnection(constr); 6 try 7 { 8 con.Open(); 9 SqlCommand cmd = new SqlCommand(&quo

ConvertHelper与泛型集合

在机房重构时,我们经常会用到ConvertHelper.它把从数据库中查询到的dateTable(也是一个临时表)转化为泛型,然后再填充到DataGridView控件中.ConvertHelper类有两点体现了面向对象的思想.一是因为它是经常被使用而被封装起来的类:二是因为它的返回值是泛型集合,泛型集合使存储数据时灵活而安全,也体现了面向对象的思想. ConvertHelper与sqlHelper 一开始接触ConvertHelper,以为它和sqlHelper一样,后来发现它们因为作用不同引用